openresty / openresty/lua-nginx-module

UDP socket closes after first invocation

Open
#1,329 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
11.8k
Forks
2.1k
Avg merge
6h 1m
Merged PRs (30d)
6

Description

My nginx config file calls my lua file with rewrite_by_lua_file /etc/nginx/conf.d/start.lua;

The start.lua application then calls the main app that I have:

package.path = package.path .. ';/path/to/app/?.lua'
local app = require('app.init');
runtime.start();

This application has the hierarchy of

clients/
    metrics.lua
   ...
config.lua
init.lua

In the metrics.lua I instantiate a socket using

local socket = ngx.socket
local udp = socket.udp()
local ok, err = udp:setpeername(config.host, config.port)
local metrics = {}

function metrics.incSomeMetric ...

And I use udp:send when I call my metric publisher to send publish metrics to my datadog agent. All works fine on the first invocation. But any subsequent invocation givers me: 16950#0: *14 attempt to send data on a closed socket

If I collapse all the lua files into a single file inside /etc/nginx/conf.d/start.lua;, everything works fine. Seems like udp connection is closed, but upon more requests, the metrics.lua has already been loaded, so the udp:setpeername is not called again.

My work around right now is to actually have

-- metrics.lua

function _get()
    local udp = socket.udp()
    local ok, err = udp:setpeername(config.host, config.port)
    return udp
end

function metrics.incSomeMetric()
    local s = _get()
    s:send(...)
    s:close()
end

So every time I call my metric, I'm creating a new connection, sending my metric, and closing it. Is this normal? Am I doing something wrong?

I realize that from https://github.com/openresty/lua-nginx-module#udpsockclose, it mentions that the socket is closed when http request completes. My issue is /etc/nginx/conf.d/start.lua; doesn't seem to bootstrap everything the second time. I tried to add logger inside all of my files, and they are all called just ONCE after nginx service restarts. I can make as many curl requests as I want, but I only get one logger information.

In my real case example, within one http request, I may call the metrics agent a few times to publish different metrics. So I don't want to create/close a socket n times per request.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the issue's start.lua and metrics.lua flow, then read the lua-nginx-module udpsockclose documentation linked in the report. Trace when rewrite_by_lua_file, require('app.init'), and udp:setpeername are invoked across requests. Done means the socket lifecycle and a supported way to reuse it for multiple metrics in one request are clearly established.

Written by the indexing model from the issue text.

Assessment

Tech stack
lua, nginx
Domain
backend, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.