تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Octane container cloning0:00

In a previous lesson, we mentioned that Octane clones a new container instance for every request. So, we have the original application instance that's created when the Octane worker starts, and we have the clone for every request. In this lesson, we will see the side effects of this. And generally, we want to avoid having our request handling logic interact with services in two different container instances. This could lead to an inconsistent and unpredictable behavior. The bugs that could be caused by this are very difficult to diagnose and solve. So avoiding this saved us from the trouble.

Injecting container into service0:37

The bugs that could be caused by this are very difficult to diagnose and solve. So avoiding this saved us from the trouble. Let's take a look. Let's say our store service requires an instance of the Laravel container. The callback in here receives an instance of the container by default. So we can pass this instance to the service like this. And then inside the service class, we add a constructor, receive the application instance, and store it into a property. Now let's add a method that returns this app instance so we can inspect it from outside the service.

Now let's add a method that returns this app instance so we can inspect it from outside the service. Let's call it app, and return the app property. Now let's go to the routes file, remove this, and change the output to return an array. In the first element of the array, we are going to return the object hash of the application instance. And in the second element, we will return the object hash of the instance we have inside the store service. So store, and then call the app method. The spl_object_hash function returns the unique hash of the given object.

So store, and then call the app method. The spl_object_hash function returns the unique hash of the given object. In a regular php fpm setup, these hashes will match as there is only a single application instance to deal with. Now let's run the octane server and see what we get. Now let's go to the browser, refresh, and we can see that the hashes match, similar to php fpm. That's because the singleton is resolved once for every request. As we saw earlier. Now let's resolve it in the put method of the service provider.

Demonstrating hash mismatch2:42

As we saw earlier. Now let's resolve it in the put method of the ServiceProvider. Then restart the server, and visit the browser. And here you can see that the hashes don't match. The container instance used in the request is different from the container instance passed to the store service. And if we refresh, we get a different hash for the request instance, while the hash of the instance inside the store service is the same. If we refresh again, we get a different request instance, while the instance in the store service is still the same.

Fixing with closure resolution3:22

If we refresh again, we get a different request instance, while the instance in the store service is still the same. That's because the store service was initialized when the octane worker started. So the app instance it received is the original container instance, not the request instance. And to deal with this, we could pass a closure instead. And inside the closure, we return container get instance, which will return the current container instance. And then inside the service itself, this is now a closure. So we call callUserFunction and pass the closure here. Now let's restart octane, visit the browser and refresh.

So we call user function and pass the closure here. Now let's restart octane, visit the browser and refresh. And here we go, the hashes match. And if we refresh again, they still match. That is the behavior we expect. We don't want to interact with multiple container instances while handling a single request, which could lead to nasty inconsistency bugs that will be very difficult to track down. Same concept applies when a service requires an instance of the current request. If we pass the request instance to a warm singleton, it won't be the same request instance the rest of the application uses.

Applying pattern to requests4:53

If we pass the request instance to a warm singleton, it won't be the same request instance the rest of the application uses. And to avoid that, pass a closure that resolves the current request from the request container and return it. Then inside the service, call the closure, extract the request instance and use it. I hope this is clear to you by now. And I will see you in the next lesson.

Laravel ContainerManaging Singletons

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟