Shared Nothing in PHP0:00
How PHP Works If you have ever looked into how PHP works by default compared to how Java works, for example, you will know that it is based on the Shared Nothing model. In this model, no resources are shared between requests. They all get released after the request has been handled. And this has been the case for the past 27 years of PHP. This is a simpler programming model that attracted many developers to the language throughout its history. Memory management is a painful task,
to the language throughout its history. Memory management is a painful task, and the ability to avoid it gave the language a huge audience. With php, there is no way, for example, that the authenticated user from a previous request is used for the current request if the two requests weren't initiated by the same user. This model also eliminates the risk of handling requests with a broken context, one that erred and got corrupted by a previous request. What I'm trying to say here is that php developers
Octane and Shared Memory1:03
one that erred and got corrupted by a previous request. What I'm trying to say here is that php developers and package maintainers are used to this model. They like it, and they wrote their code around it. To come now, after all these years, and introduce something like Octane and expect people and package developers to adapt for a shared memory model is not realistic. For that reason, Octane does its best to ease in the concept of shared memory PHP to the Laravel community.
Cloning Application per Request1:30
For that reason, Octane does its best to ease in the concept of shared memory PHP to the Laravel community. It does that by clearing part of the shared state between requests to avoid unintended bugs that may come out of it. Let's see how Octane does it. We know by now that when the worker starts, the Laravel application is created and the service container is bootstrapped. For every request that comes in, Octane creates a clone from the application instance. Let's call this application instance the original application instance.
Octane creates a clone from the application instance. Let's call this application instance the original application instance and the clone the request application instance. This cloning allows Octane to delete some container instance that got resolved in a previous request and start a new request with a fresh request application instance without any mutations that happened in a previous request. Next, Octane clones the configuration repository instance from the original container and sets it as the current repository instance in the request container.
Rebinding Container References2:35
from the original container and sets it as the current repository instance in the request container. That way, any mutations that happen to the configuration values in a request doesn't affect a future request. We will start every request with a fresh configuration repository. Next, Octane goes through multiple services in the request container and sets the current container instance as the request container instance. As you may know, php objects are passed by reference, not by value. So, all container services that require access to the container object will refer to the original container object,
So, all container services that require access to the container object will refer to the original container object, since that's where the object reference is set. By mutating these services and changing the container references to point to the request container, it avoids some nasty bugs that could result from multiple services talking to two different container instances. Maybe that doesn't make any sense right now, but I promise you we will see examples in a future lesson, and you will get it.
Flushing Service State3:42
but I promise you we will see examples in a future lesson, and you will get it. Now, finally, Octane flushes the state of multiple services so the request starts with a fresh state. Things like the state of whether the database records has been modified or not, which affects which PDO instance will be used for read connections, the read one or the write connection. It also flushes the query log and the log context that share details about the current request in log files.
It also flushes the query log and the log context that share details about the current request in log files. The array cache driver is also flushed, as it's supposed to live for the duration of one request only, that's what people would expect. And Octane does similar flushing to multiple first-party packages as well, like Telescope and Socialite, and some other packages like Livewire and Inertia. The end result is that we will have a mix between shared nothing and shared memory models in the Octane-powered application.
The end result is that we will have a mix between shared nothing and shared memory models in the Octane-powered application. In other words, some parts of the state will be shared between requests, while other parts will be flushed in between requests. And while this helps us ease into the shared memory model without having to do much changes to our application, there is still a chance you might have problems with third-party packages that haven't yet adapted for the shared memory model. The Octane team published a few guidelines on how to avoid leaking the state between requests unexpectedly,
Guidelines and Termination5:17
The Octane team published a few guidelines on how to avoid leaking the state between requests unexpectedly, and we will look into these in a future lesson. Now, Laravel package maintainers need to check these guidelines out and ensure they follow them in their code so that their packages work under Octane without a problem. Anyway, after the request application instance handles a request, Octane sends the response back to the master SWOL process to then send it back to the client. And before terminating the request,
to then send it back to the client. And before terminating the request, Octane calls all terminable middleware registered in the app and all terminating callbacks registered in the container. This gives us the same experience we have when running Laravel under regular php FPM. Now, with our understanding of how Octane handles incoming requests, let's review the guidelines Octane gives us for ensuring our application and packages don't get into any issues with the shared memory model.
for ensuring our application and packages don't get into any issues with the shared memory model. And that's for the next lesson. I will see you then.
