Skip to content

Latest commit

 

History

History
72 lines (59 loc) · 2.44 KB

finalizers.md

File metadata and controls

72 lines (59 loc) · 2.44 KB

Framework - Finalizers

Most of the framework components does not require any resetting after the request completion. However, there are multiple use-cases when you might want to reset your library after the user request is complete.

Prioritize usage of IoC scopes over finalizers.

FinalizerInterface

Use Spiral\Boot\FinalizerInterface

/**
 * Used to close resources and connections for long running processes.
 */
interface FinalizerInterface
{
    /**
     * Finalizers are executed after every request and used for garbage collection
     * or to close open connections.
     *
     * @param callable $finalizer
     */
    public function addFinalizer(callable $finalizer);
    
    /**
     * Finalize execution.
     *
     * @param bool $terminate Set to true if finalization is caused on application termination.
     */
    public function finalize(bool $terminate = false);
}

All of the application dispatchers will invoke the finalizer. During:

  • HTTP request complete
  • HTTP request failed with error
  • job is complete
  • job failed with error
  • GRPC call complete
  • GRPC call failed with error
  • console command is complete

Attention, the finalizer will only be invoked if the specific dispatcher has been started. You can freely invoke app commands and HTTP methods without using dispatcher directly and without resetting your services after each request.

Your handler will receive the first bool argument, which specifies if the app is going to terminate after the request.

Note, avoid resetting IoC setting in finalizer as it might lead to some singleton service cache previous service version.

Example Finalizer

We can use a finalizer to demonstrate how to close the database connection after every request automatically. It can be useful if you run a lot of workers (or lambda functions) and do not want to consume all of the database sockets.

// in bootloader
/**
 * @param FinalizerInterface $finalizer
 * @param ContainerInterface $container
 */
public function boot(FinalizerInterface $finalizer, ContainerInterface $container)
{
    $finalizer->addFinalizer(function () use ($container) {
        /** @var DatabaseManager $dbal */
        $dbal = $container->get(DatabaseManager::class);
 
        foreach ($dbal->getDrivers() as $driver) {
            $driver->disconnect();
        }
    });
}

You can find such bootloader already included with the framework and available as Spiral\Bootloader\Database\DisconnectsBootloader.