Coroutines in php?

Hi, I am looking for a way to implement a coroutine in a php file. The idea is that I have lengthy processes that should be able to work for hours or days. Thus, other php files will call functions in the same file as coroutine to update something, and then call a function like $coroutine.process() , which forces the coroutine to continue from its last exit. This is done so as not to use a large state machine.

I think that the php file of the coroutine file will not actually be launched when it works, but at a given processing time, it will be entered from above and use something like a switch or goto to restart from the previous lesson. Then, when it reaches the next damage, the file will save its current state somewhere (for example, a session or database), and then exit.

Has anyone heard of this or a metaphor like this? Bonus points for aggregating and managing multiple coroutines under the same collection in some way, possibly with threadlike support, so that the thread continues in one place when they end (a bit like Go).

UPDATE: php 5.5.0 added support for generators and coroutines:

https://github.com/php/php-src/blob/php-5.5.0/NEWS

https://wiki.php.net/rfc/generators

I have not tried it yet, so maybe someone can offer an example with barebones. I am trying to convert a state machine into a coroutine. So, for example, the switch command inside the for loop (whose flow is difficult to observe, and the probability of error when adding more states) is converted to a cooperative flow, where each decision point is easy to see in an ordered linear flow, which is paused to change the state with the keyword yield.

A concrete example of this is that you are writing an elevator controller. Instead of deciding whether to read the state of the buttons based on the state of the elevator (STATE_RISING, STATE_LOWERING, STATE_WAITING, etc.), you write one cycle with sub-loops that are executed while the elevator is in each state. Therefore, when he rises, he does not lower, and he will not read any buttons except the emergency button. This may not seem very complicated, but in a complex state computer, such as a chat server, it is almost impossible to update the state machine without introducing subtle errors. While the version of the joint version (coroutine) has a clearly visible stream, which is easier to debug.

+4
source share
3 answers

PHP does not support coroutines.

I would write a PHP extension with setcontext() , of course, assuming you are targeting Unix platforms.

Here's a StackOverflow question about getting started with PHP extensions: Getting started with a PHP extension .

Why setcontext() ? Little is known that setcontext() can be used for coroutines. Just replace the context when calling another coroutine.

+3
source

I am writing the second answer because there seems to be a different approach to PHP commands.

With Comet, HTTP responses are durable. Small pieces of <script> are sent from time to time, and JavaScript is executed by the browser as they arrive. The response may pause for a long time, waiting for the event. 2001 I wrote a small hosting chat chat server in Java using this technique. I was abroad for six months and I was homesick and used this to chat with my parents and my friends at home.

The chat server showed me that an HTTP request can trigger other HTTP responses. It looks like a coroutine. All HTTP responses wait for the event, and if the event is used for the response, it processes the processing and then sleeps again after it has called another response.

You need an environment where PHP handles communication with each other. Files are a simple tool, but I think the database will be better suited. My old chat server used a log file. Chat messages were added to the log file, and all chat processes were constantly read from the end of the log file in an endless loop. PHP supports sockets for direct communication, but this requires a different configuration.

To get started, I offer the following two functions:

 function get_message() { # Check medium. Return a message; or NULL if there are no messages waiting. } function send_message($message) { # Write a message to the medium. } 

Your coroutines are executed as follows:

 while (1) { sleep(1); // go easy on the CPU $message = get_message(); if ($message === NULL) continue; # Your coroutine is now active. Act on the message. # You can send send messages to other coroutines. # You also can send <script> chunks to the browser, like this: echo '<script type="text/javascript">'; echo '// Your JavaScript code'; echo '</script>'; flush(); # Yield } 

To use use continue , because it restarts the while (1) waiting for messages. Corvutin also displays at the end of the cycle.

You can provide your coroutine identifiers and / or develop a subscription model in which some coroutines listen on some messages, but not all.

Edit:

Sadly, PHP and Apache are not very suitable for a scalable solution. Even if in most cases coroutines do nothing, they conceive memory as processes, and Apache begins to deceive memory if there are too many, maybe for several thousand coroutines. Java is not much better, but since my chat server was closed, I had no performance issues. There have never been more than 10 users accessing it simultaneously.

Ningx, Node.js or Erlang have decided it better.

0
source

The Swoolle Coroutine library provides go for coroutines for PHP. Each coroutine adds only 8 KB of RAM for each process. It provides the coroutine API with expected core functions (such as profitability and renewal), coro utilities such as the coroutine iterator, and built-in coroutine built-in consoles such as file system and network functions (socket clients and servers, client and server redis, MySQL client, etc.).

The second element of your question - the ability to have long coroutines - this is probably not a good idea if you do not save the state of the crown in the session and do not allow the crown to end / close. Otherwise, the request will have to reside as long as the coroutine. If the service is hosted on a long-lived PHP script, the script is simpler, and the coroutine will just live until it is allowed / forced to close.

Swoolle is compared to Node.js and Go services and is used in many production services that regularly host 500K + TCP connections. This is a little known stone for PHP, in large part because it was developed in China, and a lot of support and documentation is limited to Chinese speakers.

A good point for Swoolle is that its PHP classes wrap an expansive C / C ++ api, designed to allow all of its functions to be used without PHP. The same source can be easily compiled as a PHP extension and / or standard library for both * NIX and Windows systems.

-2
source

Source: https://habr.com/ru/post/1440348/


All Articles