Hello!
On Wed, Jan 7, 2015 at 12:23 AM, Andre Hagenbruch wrote:
> I'm currently investigating moving our Django based API to OpenResty.
> One of our endpoints requires the communication with a backend server
> over raw TCP which you can see here:
>
> <https://gist.github.com/ahagenbruch/f35c508217894fc24b6f>
>
Several obvious issues:
1. you are not properly handling errors returned by the cosocket API
functions like send(), receive(), and setkeepalive(). You should break
from your "while true" loop when such errors happen (that is, receive
returns nil and an error string) otherwise you will enter infinite
tight loop and exhaust all the CPU time for no good. (Always be *very*
careful about such "while true" loops.)
2. you are calling os.time() which involves expensive system calls
which can hurt the performance in a noticeable way. Better call
ngx.now() instead.
3. table.insert() involves getting the table length everytime, while
getting the table length is not of the O(1) time complexity. Better
keep track of the current table length yourself and use "tab[index] =
val" instead.
4. string.match() cannot be JIT compiled even with the latest LuaJIT.
Better use the ngx.re API and the lua-resty-core library instead.
5. Use ngx.log() to log errors instead of using ngx.say() to print the
error to the client. This way you can see errors in your nginx
error.log file.
> Now, the strange thing is that this code works when it's in the
> nginx.conf file but not when I include it via "content_by_lua_file". In
> the latter case I'm constantly running into "lua tcp socket read timed
> out" which is repeated three times
It does not really make sense to me because content_by_lua and
content_by_lua_file use exactly the same code path for cosocket
operations (and any other API functions). The only difference is the
special escaping sequences required for the former, as documented
here:
https://github.com/openresty/lua-nginx-module#special-pcre-sequences
As I've suggested, better handle the cosocket errors yourself on the
Lua land and disable the automatic cosocket error logging by
configuring
lua_socket_log_errors off;
See https://github.com/openresty/lua-nginx-module#lua_socket_log_errors
for more details.
> and then the log gets flooded with
> "attempt to receive data on a closed socket: u:0000000040B8FB40,
> c:00007F367367F298, ft:0 eof:1" messages.
>
This is because you did not handle the error case and your "while
true" loop enters a tight loop (when a fatal error happens on a
cosocket object, any subsequent operations will yield the nil,
"closed" return values immediately).
Regards,
-agentzh