adamdruppe / arsd

This is a collection of modules that I've released over the years. Most of them stand alone, or have just one or two dependencies in here, so you don't have to download this whole repo.
http://arsd-official.dpldocs.info/arsd.html
530 stars 127 forks source link

cgi.d : cgi_no_threads no supported by websocket server #248

Closed andre2007 closed 4 years ago

andre2007 commented 4 years ago

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?

adamdruppe commented 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.

adamdruppe commented 4 years ago

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.

andre2007 commented 4 years ago

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())
adamdruppe commented 4 years ago

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.)

andre2007 commented 4 years ago

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)