swoole / swoole-src

🚀 Coroutine-based concurrency library for PHP
https://www.swoole.com
Apache License 2.0
18.44k stars 3.16k forks source link

task_async and coroutines #2130

Closed ghost closed 5 years ago

ghost commented 5 years ago

If i do not need onFinish() in relevant cases and only use taskwait, is it save to start coroutines in taskworkers?

https://wiki.swoole.com/wiki/page/1014.html

task_async 不稳定特性: 不推荐使用 注意: 由于运行模式的改变, 可能会出现向下不兼容的表现 (如信号处理等) 该选项为true时, task进程会变为异步模式, 允许使用异步/协程API, onTask回调不会自动创建协程, 需要手动创建, 此时使用task->finish可能会产生问题.

Does this mean problems with onFinish() or $server->finish()? Is task_async completely marked as unstable or is it just a notice because of handling of $server?

Help me translate understanding please ☺️

jobs-git commented 5 years ago

Task_async Unstable characteristics: Not recommended Note: Due to changes in the operating mode, there may be downward incompatibility (eg signal processing, etc.) When this option is true, the task process will become asynchronous mode, allowing the use of the asynchronous / coroutine API, the onTask callback will not automatically create a coroutine, you need to create it manually, using task->finish may cause problems.

ghost commented 5 years ago

@jobs-git thank you, i use browser translation myself, it's a question about the underlying morely in exact meaning of that :wink:

As we are going to use coroutines wherever possible, maybe it's incomplete just actually. Maybe, it's about correct handling. Maybe some other differences which maybe erroring in only 1 of 1000 cases, do not know

ghost commented 5 years ago

@jobs-git btw: do you know https://wiki.swoole.com/wiki/index/prid-1 This documentation is great, too :+1:

Understandig source code completely is a little bit harder in such a complex fain-grained fast growing software :relaxed:

jobs-git commented 5 years ago

I could try to help it translate in the future, the google translator seems to be close in doing it.

ghost commented 5 years ago

It's not about translation, it's about exactly meaning

twose commented 5 years ago

if you are using the coroutine, you don't have to try to use the task processes. Instead of sending tasks to other processes, why not send these tasks to the other coroutine? No memory isolation, no serialization expenses, no interprocess communication expenses, so why do you have to use task processes to run the async codes? Although developers really want to do this, I have always opposed, because many people don’t understand what is the coroutine, what it can bring to us.

twose commented 5 years ago

about task->finish, task processes were designed to synchronize API, if you run the async code and use it, how can we know which task was completed.

ghost commented 5 years ago

Oh, twosee, thanks, that's right.

I skipped coroutines till now only because of sharing a channel. What's about workers in multicore environments?

With IPC i can handle their scopes, like

if ($server->worker_id === X) {
  # in scope of task X
}

So, what's about sharing channels in 'worker_num' => 10 for example, via SWOOLE_BASE or SWOOLE_PROCESS?

And: are workers obsolete now?

How to use channels in this case? What's their scope?

Maybe, i have not thought enough about, it's all in documentation of coroutines? Than i will start reading it :relaxed:


about task->finish, task processes were designed to synchronize API, if you run the async code and use it, how can we know which task was completed.

Hmm. I handled it due to the $server object which onTask gives. I tested thousands of different requests via queue. As i am in the same taskworker scope discribed above, this should work?

This was a test to handle only one sqlite queue for one sqlite3 db file as sqlite has only table-lock, no row-lock etc.

twose commented 5 years ago

Task processes are really helpful for using multicore. But most developers don't have such deep demands, Swoole has no multithreaded, this is a trade-off in the difficulty of development, but it does lead to the problems when we have lots of CPU cores. And channel's scope is the process to which it belongs to.

twose commented 5 years ago

I can't understand what you said at the end of the comment. (English reason)

ghost commented 5 years ago

Deepest demands, twose :relaxed:

I build exactly the same software as you, but not for PHP and before Golang pushes coroutines. As i was kicked out due to time-break, i stopped my work when http/2 arrives, because i felt to slow to write a parser again.

But you are doing it for PHP and with coroutines. That's why i love this project :relaxed:

It's ok for me to go with nghttp2, because i do not like it anyway. Maybe, http/3 is the next big thing which is worth to do it...

for this issue: i will have following questions and after that, i will close it :wink: thx

ghost commented 5 years ago

Just to close this issue

Initially idea was to queue sqlite. Therefore i have used taskworker (both, task_async set and unset) by running queue in a save scope of a taskworker, whereby it's callable globally. This works perfectly due to referencing $server to each finish(). I have testet this (10 worker, 10 taskworker) by calling taskworkers thousands of times with requests of different queries (insert x, update y, select z) with random data from random workers via $server->taskwait() from several scripts - without any lost.

But this kind of queue makes no sense in general, as sqlite is called synchronously per se.

It was nice to test taskworkers in such a complex benchmark and get a feeling for their power :muscle: :relaxed:

But lastly there is no relevance to queue sqlite this way, as it locks per write and nothing else.

But, nice game to study taskworkers :+1: