Closed andre2007 closed 4 years ago
On Tue, Mar 24, 2020 at 10:30:44PM -0700, andre2007 wrote:
As far as I can see the version
cgi_no_threads
is only for debugging and also has no effect on a WebSocket server.
did you try it? it might just work.
but indeed i don't really recommend it, nothing in there is eally designed for single threading, it makes the server liable to hang ups by one user handle.
there's also a variable processPoolSize if you are on Linux and specifically using -version=embedded_httpd_processes
you can set that to 1 before calling cgiMainImpl and kinda get the same thing
or just modify your copy of the code, line 4112 has the thread pool declaration and it can be downsized.
Thanks Adam, setting processPoolSize to 1 has the desired effect.
Yes I tested cgi_no_threads with this code and it has no effect. The text "initialize map" should only written once to console but is written 8 times (processPoolSize).
/+ dub.sdl:
name "server"
dependency "arsd-official:cgi" version="6.0.2"
versions "cgi_no_threads"
+/
import std;
import arsd.cgi;
void main()
{
writeln("Listening on port 5000");
cgiMainImpl!((cgi) { websocketEcho(cgi); }, Cgi, defaultMaxContentLength)(["--port", "5000"]);
}
static string[string] myMap;
void websocketEcho(Cgi cgi) {
assert(cgi.websocketRequested(), "i want a web socket!");
auto websocket = cgi.acceptWebsocket();
while(websocket.recvAvailable(300.seconds))
{
auto msg = websocket.recv();
if (msg.opcode == WebSocketOpcode.close) break;
if (myMap.keys.length == 0)
{
writeln("initialize map");
myMap["foo"] = "bar";
}
websocket.send(msg.data);
}
websocket.close();
}
client.py
import asyncio
import websockets
async def hello():
data = b'\x00\x00\x00'
uri = "ws://localhost:5000"
for x in range(0, 50):
async with websockets.connect(uri) as websocket:
await websocket.send(data)
recv_buffer = await websocket.recv()
assert(recv_buffer == data)
asyncio.get_event_loop().run_until_complete(hello())
On Wed, Mar 25, 2020 at 09:56:00PM -0700, andre2007 wrote:
Yes I tested cgi_no_threads with this code and it has no effect. The text "initialize map" should only written once to console but is written 8 times (processPoolSize).
no_threads only applies when paired with embedded_httpd_threads.
the default on linux is embedded_httpd_processes which uses processPoolSize instead. On Windows it defaults to the threads implementation. So difference there on platform but you can specify with -version... not sure if the dub configurations will fully respect it though, i have never tried.
(none of this is really documented since it is all really internal implementation details in my mind. well, the httpd_processes vs httpd_threads is documented, but none of the hacky tweaks.)
Thanks for the explanation. You are right, the SDL versions statement does not work. I created a DUB issue: https://github.com/dlang/dub/issues/1909
I forgot I can't use embedded_httpd_threads
at the moment as lambdas are not accepted
(https://github.com/adamdruppe/arsd/issues/241#issuecomment-589219904)
In my scenario, I have a WebSocket server which provides access to a third party library which has a state. WebSocket requests will will be triggered only by 1 client and in sequence.
As far as I can see the version
cgi_no_threads
is only for debugging and also has no effect on a WebSocket server.Is there any possibility to force a single threaded WebSocket server?