-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
don't check size for streaming #1
Comments
and I think self.exit_flag is unnecessary. "while true do" would be the same and still able to break the loop on error. |
There'll be some problems if client reuse the same connection to issue multiple requests and the requests are not continuous. Imagine the following scenario between a client and our server ( |-------------------4096 bytes----------------------|-------------------4096 bytes----------------------| If client finnished several http requests after This problem will not exists if the connection is only used once or the requests are issued continously. The |
You are wrongly understanding the semantics of recv(). I'm not sure about how it is possible to reuse the connection in the forwarding mode. Please tell me the RFC Standard(s) if there are. |
The receive() API of ngx cosocket is wrapped from nginx's own event loop and is not working as the standard recv() call. According to document, "This method will not return until it reads exactly this size of data or an error occurs." I've set up a echo server with the following code:
You can try it using |
@fffonion That is shocking that echo server cannot be implemented in an easy way, the current receive() call behavior will largely limit the usefulness of stream-lua-nginx-module. :( I'm sorry I didn't find that in the first place. so it becomes clear that the issue depends on an API change from the upstream project. |
a "partial" argument can be added to the receive() call like the read_bytes() in tornado.iostream module. the current receive() function waits for (bytes >= (ssize_t) u->rest) in ngx_stream_lua_socket_read_chunk.
a new input_filter function which do the following should work, u->rest should be 0:
|
Please test the patch for stream-lua-nginx-module so receive('*p') can be introduced. |
I don't think that'll be the principle of writing coroutines. I suppose a echo server can be implemented like: while true do
local buf = sock:receive("*p")
if buf then
-- do something of yield some data
end
end The code above will block a nginx worker process if client is not sending any data. And ngx_lua has no mechanism like callback (and shouldn't have one) like tornado. |
it should block in the same way as line reading (*l), but returns data as soon as arrived. you mean *l will block the process? |
I misread your code before. That makes sense to me. |
hmm. that patch makes writing echo and other kinds of proxy server in openresty possible. actually the same API issue comes from luasocket (buffer.c), and later ported to openresty project. anyway, thanks for your project that revealed the issues in upstream projects, so some future contributions can be expected. |
Just for some results I found after doing several tests: This can be convinced by comparing cpu time between current This leads to a problem that, if the server or client has a slow connection to our proxy, |
hmm... the final method would be a native forwarding loop, like ngx_stream_proxy_process in ngx_stream_proxy_module.c. I can accept the performance fact, but the semantics is different. |
native module will defintely be a better solution. while limit the implementation in lua land, whether to use stream forwarding or read length seems to be a tradeoff🌚. |
I think that only means the difference of the times of string copy (or build?) operations. |
yes and that'll lead to a dilemma between "more performance" or "less system resources". at current state I think both implementations are acceptable :smile |
I don't have enough time to implement a forwarder that bypass the lua string. |
well i'm not asking for anything. it's just a discussion. |
please leave this open. the cpu usage issue comes from luaL_addlstring implementation in luajit (lib_aux.c). it calls luaL_addchar for length() times. the luaL_buffer struct in luajit can only store strings with length up to LUAL_BUFFERSIZE, while in lua 5.3 it is able to use luaL_prepbuffsize to prepare the buffer, and luaL_addlstring uses memcpy directly. |
as defined in src/lauxlib.h, we can do memcpy up to the lesser of length or bufffree(B). then do a emptybuffer(B) && adjuststack(B).
|
patch uploaded to gist: https://gist.github.com/fcicq/5894ea946a27f8782188148fd09275e1 |
please attach a new flamegraph in your workload. I'm also considering a new method similar with select(), it should match the raw forwarding speed if implemented. |
Thanks for your work and it would be more helpful if you can send PR to luajit. 😄 |
The size checking is not actually required as long as no changes are applied to the data in _upl() and _dwn().
Currently I don't have a working env for openresty. I guess the core loop should look like this:
The text was updated successfully, but these errors were encountered: