ScalavaBreathtaking scaling for Laravel Applications.

Check it now

Laravel Application Synchronization with Redis

Laravel

Redis, a powerful in-memory data structure store, can be seamlessly integrated with Laravel applications to enhance their performance and enable efficient synchronization between multiple applications.

In this blog post, we will explore how to configure two Laravel applications to connect to a single Redis instance and utilize it for dispatching and processing synchronization jobs. We will also demonstrate how to set a custom key prefix for Redis to maintain data isolation between default queue and synchronization queue. Let's dive in!

1. Configuring Redis Connections

Open the config/database.php file in both Laravel applications and locate the redis array.

Add a new connection configuration under the 'connections' array for the Redis instance named "sync".

Ensure that you set custom prefix in options key of connection. Laravel is generating prefix for each queued job by default.

By this setting we will override it and make it same on both applications.

Here's an example of how the configuration should look:

'connections' => [
    // Other connections...

    'sync' => [
        'url' => env('SYNC_REDIS_URL'),
        'host' => env('SYNC_REDIS_HOST', '127.0.0.1'),
        'port' => env('SYNC_REDIS_PORT', '6379'),
        'password' => env('SYNC_REDIS_PASSWORD', null),
        'database' => env('SYNC_REDIS_DB', '1'),
        'options' => [
            'prefix' => env('SYNC_REDIS_PREFIX', 'app_sync_')
        ],
    ],
],

Ensure that the SYNC_REDIS_HOST, SYNC_REDIS_PORT, SYNC_REDIS_PASSWORD values are set according to your Redis server configuration that will be shared between applications.

2. Creating the Synchronization Jobs

2.1 First Laravel Application (Source)

In the first Laravel application, create the SynchronizeItem job and use the "sync" connection.

The handle method is not necessary since first Laravel application will not be processing this job, so only properties of the job are required to be same as job defined in second Laravel application.

Here's an example of how the job should look:

class SynchronizeItem implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct(public array $data)
    {
        $this->onConnection('sync');
    }

    public function handle(): void
    {
        // This job is just definition, processing is made using Job class in destination Laravel Application.
    }
}

2.2 Second Laravel Application (Destination)

In the second Laravel application, create the SynchronizeItem job and use the "sync" connection.

Now, we will define the handle method to store data or process them in our destination Laravel Application.

Make sure that properties are exactly same as in job defined in first Laravel Application.

Here's an example of how the job should look:

class SynchronizeItem implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct(public array $data)
    {
        $this->onConnection('sync');
    }

    public function handle(): void
    {
        // Processing of data. For example check the type of synchronization item and dispatch event.
        
        match($this->data['type']) {
            SynchronizationType::Transaction->value => $this->processTransaction(),
        }
    }
    
    protected function processTransaction(): void
    {
        TransactionSynchronized::dispatch($this->data);
    }
}

3. Dispatching the Synchronization Job

Once your job class is written, you can dispatch it by using the dispatch method on the actual job in first Laravel Application.

The job's constructor will receive the following arguments that were passed to the dispatch method:

// Somewhere in your code

SynchronizeItem::dispatch([
    'type' => 'Transaction',
    'item' => [
        'currency' => 'EUR',
        'amountInCents' => 150_000,
    ],
]);

The job will be pushed into queue that uses connection of shared Redis instance.

4. Queue Worker for shared Redis connection

Once you have dispatched your SynchronizeItem job to the queue we need to start queue worker on second Laravel Application for processing of synchronization jobs.

Before starting it we need to define this queue in our config/queue.php configuration file.

Here's an example of how the configuration should look:

'connections' => [
    // Other connections...

    'sync' => [
        'driver' => 'redis',
        'connection' => 'sync', // Connection defined in database.php configuration
        'queue' => env('SYNC_REDIS_QUEUE', 'default'), // You can define custom queue in job or while dispatching, for now we keep it as "default"
        'retry_after' => 90,
        'block_for' => null,
        'after_commit' => false,
    ],
]

Once we have defined sync queue in second Laravel Application we can start queue worker process.

php artisan queue:work sync

This command starts the queue worker, which listens to the "default" queue on "sync" connection and processes jobs dispatched to it from first Laravel Application.

Conclusion

In this blog post, we explored how to configure two Laravel applications to connect to a single Redis instance and use it for dispatching and processing synchronization jobs.

By following the steps outlined above, you can ensure seamless communication between your Laravel applications and leverage the power of Redis to enhance performance.

Additionally, we learned how to use custom queue connection, and set a custom key prefix for Redis to maintain data isolation from other jobs.

We hope this guide helps you in building efficient and synchronized Laravel applications.

References:

Laravel Documentation: Queues

Laravel Documentation: Redis

Start your idea today.

Ready to start your business idea? Get in touch with us and we will handle everything else.