Hi there, I'm trying to setup a simple TCP service in lua (via `core.register_service()`) to accept several lines of text at a time from an external process and I've recently run into issues when that lua yields (either forcibly or intentionally). More specifically it appears that whenever the service function yields, the data that has already been received but not yet processed is lost because the channel's buffer gets cleared out. I can reliably reproduce this on 2.8.0, 3.1.0 and master as of commit 2c3d656 (latest at the time of writing), details below.
I understand that some lua contexts are not allowed to yield but its not clear if this is the case for applets/services. More broadly it's not clear to me from the documentation what context such a service runs in. The documentation for `core.register_service()` does not specify the context in which the service function will be run and while the documentation does mention an "applet" context, it appears only once under `core.thread`. So my first question is: Is a service/applet function allowed to yield? I assume so because `AppletTCP.getline()` itself yields internally if no data is immediately available. However, if they are allowed to yield then this seems like a bug since I would certainly not have expected that my TCP-based service would observe gaps in the data it receives. I can reliably reproduce this behaviour using the following setup: haproxy config: ``` global log stdout format raw local0 info lua-load haproxy_yieldtest.lua defaults log global timeout connect 10s timeout client 1m timeout server 1m listen echo bind *:9090 mode tcp tcp-request content use-service lua.print_input ``` haproxy_yieldtest.lua: ``` core.register_service("print_input", "tcp", function(applet) core.Info("Start printing input...") while true do local inputs = applet:getline() if inputs == nil or string.len(inputs) == 0 then core.Info("closing input connection") return end core.Info("Received line: "..inputs) core.yield() end end) ``` and then testing it by running this simple bash script: ``` #!/usr/bin/bash for i in $(seq 1 9999); do for j in $(seq 1 50); do echo "${i}_foo_${j}" done sleep 2 done ``` and running it with `./test_seq.sh | netcat localhost 9090`. The script prints a line ending in numbers 1 through 50 every 2 seconds. I would expect haproxy to log the same output, but instead I get the following: ``` $ ./haproxy -f haproxy_yieldtest.conf [NOTICE] (123028) : haproxy version is 3.2-dev10-2c3d65-67 [NOTICE] (123028) : path to executable is ./haproxy [WARNING] (123028) : config : hlua: please set "tune.lua.bool-sample-conversion" tunable to either "normal" or "pre-3.1-bug" explicitly to avoid ambiguities. Defaulting to "pre-3.1-bug". Connect from 127.0.0.1:52014 to 127.0.0.1:9090 (echo/TCP) Start printing input... Received line: 1_foo_1. Received line: 1_foo_18. Received line: 1_foo_36. Received line: 1_foo_39. Received line: 1_foo_40. Received line: 1_foo_49. Received line: 1_foo_50. Received line: 2_foo_1. Received line: 2_foo_38. Received line: 3_foo_1. Received line: 4_foo_1. Received line: 4_foo_35. Received line: 4_foo_41. Received line: 5_foo_1. Received line: 6_foo_1. ``` Clearly it's missing a whole lot of input lines, is this a bug or am I just trying to use services/applets to achieve something they're not meant to achieve? Any help would be much appreciated! Thanks Jacques