Open kingIZZZY2 opened 2 years ago
$server = new Swoole\WebSocket\Server('0.0.0.0',getenv('PORT'),SWOOLE_BASE);
or
$server = new Swoole\WebSocket\Server('0.0.0.0',getenv('PORT'));
$server->set(['worker_num' => 1]);
or
$server = new Swoole\WebSocket\Server('0.0.0.0',getenv('PORT'));
$server->set(['dispatch_mode' => 4]);
It will only take effect in a single process because of process isolation.
I believe I was already in an environment of 1 single worker/process, and it was still not working..
Is there some way to get worker ID or get process ID or whatever so i can prove by log / print to output whether things are happening in 1 single worker/process or not?
EDIT: OK i found how to do this. Indeed my environment would usually run 8 workers by default. If I limited to 1 then suspending & resuming works as expected! Please see the big follow-up question below
But really even across multi-worker / multi-process, how to achieve this same "promise/future" effect between any 2 Requests or even WebSocket messages even across other fibers/threads/workers/processes?
If co::suspend() / resume() / WaitGroup::wait() / done()
won't work because of process isolation, is there some other way to make Request A (no matter which worker or process) to yield to other coroutines & not block other requests or other fibers/workers/processes from functioning non-blocking, and only whenever any other code decides to "resolve" some condition EVEN from a separate isolated worker or process - then it resumes & unblocks Request A to continue and respond & end the request?
Coroutine IDs seem to be completely unrelated between Request A and Request B, sometimes even Request A and Request B both have the same identical cid! It seems they do not share a coroutine context?
For multi-process servers, you may need to use redis and its subscription feature.
Doesn't Swoole itself have any technologies which can help for this need, without even needing 3rd party stuff like redis? Anything with IPC or something like that maybe? Something with swoole events and file descriptors and epoll_wait or something? Any other cross-worker "Promise/await/resolve" system anyone implemented based on swoole?...
Maybe you can use Swoole\Table to solve it. Swoole\table can be shared by multi-process.
But Swoole table cannot persist objects & instances of complex classes, only primitives int/string/float (unless i'm wrong about that?)
Ever since you stopped thinking about the single-process mode, you've started thinking about its scalability, so we might as well think a little further. PHP + Swoole can do almost everything you can think of, including a database with a subscription feature. But I think it might be a bit troublesome for you... So, I still recommend you choose redis.
@twose Can you please explain just a little bit more how do you suggest I use redis
If I subscribe to a redis channel then how can I make my "Coroutine A" wait until a message comes from that channel? Do I loop in a while(){ ... }
loop and check if a redis pub/sub message arrived? How is it better than checking for a swoole table value?
Is there maybe a more performant way how to achieve a similar effect using the swoole Event API maybe, by using some temporary file descriptor as a suspend/resume mechanism waiting for file descriptor events?
@kingIZZZY2 This is unrelated to Swoole, but you should look at redis blocking commands. The idea is that each thread can have a coroutine subscribed to a redis blocking command, say BLPOP, and when it gets some data, start a new coroutine to process it and block on a BLPOP command again.
That way, you have threads across different servers waiting for data in some redis list, and once an item shows up there, some thread will pop that item and process it.
Question
How can I make one incoming
Swoole\Http\Server::on('Request')
to suspend/wait/yield indefinitely, and then anotherSwoole\Http\Server::on('Request')
or evenSwoole\WebSocket\Server::on('Message')
can resume/unblock/continue that waiting HTTP request?Kind of like a "Promise"
Request A
, so this request has not yet responded and is still "loading"Request B
or WebSocket\ServerMessage B
"resolves" the promiseRequest A
completes and responds and finishes1. What did you do? If possible, provide a simple script for reproducing the error.
Tried using
Swoole\Coroutine::suspend();
andSwoole\Coroutine::resume();
within an HTTP server across different HTTP requests2. What did you expect to see?
Isn't swoole able to suspend/yield one request coroutine indefinitely, and resume it from another HTTP request? Similar to Promises, begin the promise from Request A, suspend the request without responding yet, then later Request B "resolves" the promise and somehow affects Request A to resume from suspension/yielding.
3. What did you see instead?
Coroutine IDs seem to be completely unrelated between Request A and Request B, sometimes even Request A and Request B both have the same identical
cid
! It seems they do not share a coroutine context?4. What version of Swoole are you using (show your
php --ri swoole
)?5. What is your machine environment used (show your
uname -a
&php -v
&gcc -v
) ?