What if WordPress could be launched as a stateful application? #16
Replies: 2 comments 4 replies
-
|
How about enhance the functions to terminate the current coroutine instead of the whole process, except when it's the root coroutine. |
Beta Was this translation helpful? Give feedback.
-
|
I tried to go a bit further and make the WordPress state shared between coroutines. What has been done?
class WPShared
{
public static array $globals = [];
public static array $superglobals = ['_GET', '_POST', '_COOKIE', '_SERVER', '_FILES'];
public static function cloneGlobals(): void
{
foreach (WPShared::$globals as $name => $value) {
// $GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
if($name == 'wp_query') {
continue;
}
else if($name == 'wp_the_query') {
$GLOBALS[$name] = clone $value;
// alias for wp_the_query
$GLOBALS['wp_query'] = $GLOBALS[$name];
} else if(is_object($value)) {
$GLOBALS[$name] = clone $value;
} else {
$GLOBALS[$name] = $value;
}
}
$wpdbShared = WPShared::$globals['wpdb'];
unset($GLOBALS['wpdb']);
require_wp_db();
$wpdb = $GLOBALS['wpdb'];
// Copy all public properties from $wpdbShared to $wpdb
foreach ($wpdbShared as $name => $value) {
$wpdb->$name = $value;
}
}
}
foreach ($GLOBALS as $key => $value) {
// Without superglobals
if (in_array($key, WPShared::$superglobals)) continue;
WPShared::$globals[$key] = $GLOBALS[$key];
}The database is created over and over each time, and this is not quite correct code because it leads to connection exhaustion. The key benefit of this code is minimal changes to WordPress itself. Essentially, I changed just one line in one file and that’s it. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Experiments with WordPress
After implementing memory model 2, which provides isolation for
GLOBALSandSUPERGLOBALS, it became interesting to see whether this level of isolation would be sufficient for WordPress to function correctly.A quick analysis of the WordPress code confirmed that this isolation is indeed enough for it to run safely inside coroutines.
But simply running WordPress with coroutines would be too plain and unexciting.
A more ambitious idea
What if WordPress could be launched as a stateful application, where:
To achieve this, several steps were required:
Of course, launching WordPress as a fully stateful application requires additional work.
For example:
exit(), which effectively terminates the entire server;define()without considering that the code may be executed multiple times in a long-lived runtime.These behaviors are natural for classic stateless PHP, but they become problematic in a coroutine-driven, stateful architecture.
For demonstration purposes, I decided to focus only on the main page.
To avoid modifying WordPress itself, I prepared a ready-made database, did not install any additional plugins, and simply used the code from the repository as is.
As result: https://github.com/true-async/wordpress-test/blob/main/app/entrypoint.php
3–4 hours of work and you have the WordPress front page running inside a single process, over and over again.
The WordPress code itself remains essentially unchanged.
Do not assume this is a production-ready application.
The issues with
exitandredirecthave not been addressed. Therefore, whenever something triggersexit, the process returns a 503 error and this is expected behavior at this stage.Beta Was this translation helpful? Give feedback.
All reactions