Skip to content
This repository was archived by the owner on Feb 7, 2024. It is now read-only.

Commit c1bef4d

Browse files
committed
Added async redis connection
1 parent 40ee5fb commit c1bef4d

File tree

10 files changed

+677
-18
lines changed

10 files changed

+677
-18
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"illuminate/broadcasting": "^6.3|^7.0|^8.0",
4242
"illuminate/console": "^6.3|^7.0|^8.0",
4343
"illuminate/http": "^6.3|^7.0|^8.0",
44+
"illuminate/queue": "^6.3|^7.0|^8.0",
4445
"illuminate/routing": "^6.3|^7.0|^8.0",
4546
"illuminate/support": "^6.3|^7.0|^8.0",
4647
"pusher/pusher-php-server": "^3.0|^4.0",

config/websockets.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@
137137

138138
'redis' => [
139139

140-
'connection' => 'default',
140+
'connection' => env('WEBSOCKETS_REDIS_REPLICATION_CONNECTION', 'default'),
141141

142142
/*
143143
|--------------------------------------------------------------------------

docs/horizontal-scaling/redis.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,29 @@ You can set the connection name to the Redis database under `redis`:
4040
```
4141

4242
The connections can be found in your `config/database.php` file, under the `redis` key.
43+
44+
## Async Redis Queue
45+
46+
The default Redis connection also interacts with the queues. Since you might want to dispatch jobs on Redis from the server, you can encounter an anti-pattern of using a blocking I/O connection (like PhpRedis or PRedis) within the WebSockets server.
47+
48+
To solve this issue, you can configure the built-in queue driver that uses the Async Redis connection when it's possible, like within the WebSockets server. It's highly recommended to switch your queue to it if you are going to use the queues within the server controllers, for example.
49+
50+
Add the `async-redis` queue driver to your list of connections. The configuration parameters are compatible with the default `redis` driver:
51+
52+
```php
53+
'connections' => [
54+
'async-redis' => [
55+
'driver' => 'async-redis',
56+
'connection' => env('WEBSOCKETS_REDIS_REPLICATION_CONNECTION', 'default'),
57+
'queue' => env('REDIS_QUEUE', 'default'),
58+
'retry_after' => 90,
59+
'block_for' => null,
60+
],
61+
]
62+
```
63+
64+
Also, make sure that the default queue driver is set to `async-redis`:
65+
66+
```
67+
QUEUE_CONNECTION=async-redis
68+
```

src/ChannelManagers/RedisChannelManager.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,16 @@ public function getPublishClient()
519519
return $this->publishClient;
520520
}
521521

522+
/**
523+
* Get the Redis client used by other classes.
524+
*
525+
* @return Client
526+
*/
527+
public function getRedisClient()
528+
{
529+
return $this->getPublishClient();
530+
}
531+
522532
/**
523533
* Get the unique identifier for the server.
524534
*

src/Queue/AsyncRedisConnector.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace BeyondCode\LaravelWebSockets\Queue;
4+
5+
use Illuminate\Queue\Connectors\RedisConnector;
6+
7+
class AsyncRedisConnector extends RedisConnector
8+
{
9+
/**
10+
* Establish a queue connection.
11+
*
12+
* @param array $config
13+
* @return \Illuminate\Contracts\Queue\Queue
14+
*/
15+
public function connect(array $config)
16+
{
17+
return new AsyncRedisQueue(
18+
$this->redis, $config['queue'],
19+
$config['connection'] ?? $this->connection,
20+
$config['retry_after'] ?? 60,
21+
$config['block_for'] ?? null
22+
);
23+
}
24+
}

src/Queue/AsyncRedisQueue.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace BeyondCode\LaravelWebSockets\Queue;
4+
5+
use BeyondCode\LaravelWebSockets\Contracts\ChannelManager;
6+
use Illuminate\Contracts\Redis\Factory as Redis;
7+
use Illuminate\Queue\RedisQueue;
8+
9+
class AsyncRedisQueue extends RedisQueue
10+
{
11+
/**
12+
* Get the connection for the queue.
13+
*
14+
* @return \BeyondCode\LaravelWebSockets\Contracts\ChannelManager|\Illuminate\Redis\Connections\Connection
15+
*/
16+
public function getConnection()
17+
{
18+
$channelManager = $this->container->bound(ChannelManager::Class)
19+
? $this->container->make(ChannelManager::class)
20+
: null;
21+
22+
return $channelManager && method_exists($channelManager, 'getRedisClient')
23+
? $channelManager->getRedisClient()
24+
: parent::getConnection();
25+
}
26+
}

src/WebSocketsServiceProvider.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use BeyondCode\LaravelWebSockets\Dashboard\Http\Middleware\Authorize as AuthorizeDashboard;
1212
use BeyondCode\LaravelWebSockets\Server\Router;
1313
use Illuminate\Support\Facades\Gate;
14+
use Illuminate\Support\Facades\Queue;
1415
use Illuminate\Support\Facades\Route;
1516
use Illuminate\Support\ServiceProvider;
1617

@@ -36,6 +37,12 @@ public function boot()
3637
__DIR__.'/../database/migrations/0000_00_00_000000_rename_statistics_counters.php' => database_path('migrations/0000_00_00_000000_rename_statistics_counters.php'),
3738
], 'migrations');
3839

40+
$this->registerAsyncRedisQueueDriver();
41+
42+
$this->registerRouter();
43+
44+
$this->registerManagers();
45+
3946
$this->registerStatistics();
4047

4148
$this->registerDashboard();
@@ -50,8 +57,19 @@ public function boot()
5057
*/
5158
public function register()
5259
{
53-
$this->registerRouter();
54-
$this->registerManagers();
60+
//
61+
}
62+
63+
/**
64+
* Register the async, non-blocking Redis queue driver.
65+
*
66+
* @return void
67+
*/
68+
protected function registerAsyncRedisQueueDriver()
69+
{
70+
Queue::extend('async-redis', function () {
71+
return new Queue\AsyncRedisConnector($this->app['redis']);
72+
});
5573
}
5674

5775
/**

0 commit comments

Comments
 (0)