Re: Re: PHP True Async RFC Stage 5

From: Date: Mon, 17 Nov 2025 09:49:14 +0000
Subject: Re: Re: PHP True Async RFC Stage 5
References: 1 2 3 4 5 6 7 8 9 10 11 12 13 14  Groups: php.internals 
Request: Send a blank email to internals+get-129278@lists.php.net to get a copy of this message
Hello Larry Regarding the phrase about “problems with mutable shared state”. In this context, when I say “problem,” I mean something that significantly worsens development. “Not a problem” does not mean that errors never occur. It means that resolving them takes an acceptable amount of time. This phenomenon has reasonable explanations: 1. Developers usually know where they use global state. And even if they don’t, they know that this is the first thing to check. That helps a lot. 2. Bugs involving shared memory are usually easy to reproduce (which is rare in asynchronous programming). This drastically reduces debugging time. 3. In a single-threaded environment, shared-state bugs are much simpler. For example, the probability of corrupting data structures is relatively low. 4. In PHP projects, shared state is typically used in a small set of scenarios, and these scenarios are usually simple, which also minimizes the time needed to fix issues. For example: some global variable stores a SessionId. And then it turns out that an action was recorded not for the user who performed it, but for another one with a different session. In most cases, the bug report alone already points you directly to where you need to look. My point is not that you should ignore shared-memory bugs, but that you shouldn’t fear them or treat them as something huge. I also want to remind that in programming there are no “bad” approaches or technologies. Shared mutable state is a very useful thing and should be used. For caching, for storing session data, for access-rights memoization, and so on. You don’t need to avoid shared state. You need good tools, patterns, and proper practices. As for language-level abstraction, features like local $var, effects, and context will help make the code safer. Monads would also fit PHP well, as they allow expressing parallelism better than procedural code. > That's what I think we all want to NOT have in PHP. Exactly. PHP exists to save money, not to spend it. Recently there was an article about Python describing the problems caused by having multiple runtimes. > Third: So my question would be, is there a practical middle-ground? > Is there a syntax and semantics we could define that would cover *most* edge cases existing > code may have involving shared mutable state automatically Based on the current state of programming languages, there is no good solution. Only radical ones like Actors, Arenas, and so on. All of them rely on complete memory isolation. But that’s not the point. The point is that PHP still has legacy code, and you cannot just throw it away. > the RFC right now says "any IO operation, implicitly, hope that's OK." Go does the same thing, and it’s a very convenient mechanism. There is a small percentage of cases where this breaks the logic. Here is one of them: ```php $start = microtime(true); $data = file_get_contents('data.txt'); $elapsed = microtime(true) - $start; if ($elapsed > 0.001) { echo "Reading took too long\n"; } ``` The code breaks only in two cases: 1. When there is usage of mutable shared memory/shared resource 2. When there is logic based on a timer Yes, such code will break inside a coroutine. But should we be afraid of that? I don’t think so. The likelihood of this kind of logic is very low. And if needed, this case can be explicitly documented. Besides this case, special attention is also needed for: * libraries that use sockets * libraries that use threads * libraries that use processes But this does not mean there will necessarily be major or serious problems adapting the code. PHP already has experience with Swoole, and Swoole works exactly the same way as the code in this RFC. For example, adapting the RabbitMQ library for Swoole required changing about 10–20 lines of code, roughly 2–3 days of work. Most of the time was spent on testing. Regarding the hybrid function-tainting model, it is designed for compilers or static analysis. For PHP, it could be implemented like this: ```php #NoAsync function myFun() { asyncFun(); // Error <--- } function asyncFun() {} ``` This is a solvable task for static analysis.

« previous php.internals (#129278) next »