Lae/app/Support/Cluster.php

115 lines
3.1 KiB
PHP
Raw Normal View History

2023-01-04 12:18:22 +00:00
<?php
namespace App\Support;
use Illuminate\Support\Facades\Redis;
class Cluster
{
public static string $prefix = 'cluster:';
public static function isMaster(): bool
{
return config('settings.node.type') === 'master';
}
public static function isSlave(): bool
{
return config('settings.node.type') === 'slave';
}
public static function isCluster(): bool
{
return self::isMaster() || self::isSlave();
}
public static function publish($event, $data = []): void
{
Redis::publish('cluster_ready', json_encode([
2023-01-04 15:57:36 +00:00
'event' => $event,
2023-01-04 12:18:22 +00:00
'node' => [
'type' => config('settings.node.type'),
'id' => config('settings.node.id'),
'ip' => config('settings.node.ip'),
],
'data' => $data,
]));
}
2023-01-04 15:57:36 +00:00
/**
* @param string|array $events 事件名称
* @param $callback callable 回调函数,接收一个参数,为事件数据。
* @param $ignore_self bool 是否忽略此节点的消息。
*
* @return void
*/
public static function listen(string|array $events, callable $callback, bool $ignore_self = true): void
{
// socket timeout
ini_set('default_socket_timeout', -1);
Redis::subscribe('cluster_ready', function ($message) use ($events, $callback, $ignore_self) {
$message = json_decode($message, true);
if ($ignore_self && $message['node']['id'] === config('settings.node.id')) {
return;
}
if (is_array($events)) {
if (in_array($message['event'], $events)) {
$callback($message['event'], $message);
}
} else {
if ($events === '*' || $events === $message['event']) {
$callback($message['event'], $message);
}
}
});
}
2023-01-04 12:18:22 +00:00
public static function hset($key, $value, $data = []): void
{
2023-01-04 15:57:36 +00:00
Redis::hset(self::$prefix . $key, $value, json_encode($data));
2023-01-04 12:18:22 +00:00
}
public static function get($key, $default = null): string|array|null
{
2023-01-04 15:57:36 +00:00
return Redis::get(self::$prefix . $key, $default);
2023-01-04 12:18:22 +00:00
}
public static function set($key, $value, $ttl = null): void
{
2023-01-04 15:57:36 +00:00
Redis::set(self::$prefix . $key, $value, $ttl);
2023-01-04 12:18:22 +00:00
}
public static function forget($key): void
{
2023-01-04 15:57:36 +00:00
Redis::forget(self::$prefix . $key);
2023-01-04 12:18:22 +00:00
}
// forever
public static function forever($key, $value): void
{
2023-01-04 15:57:36 +00:00
self::set($key, $value, -1);
2023-01-04 12:18:22 +00:00
}
public static function hget($key, $value, $default = null): string|array|null
{
return Redis::hget($key, $value, $default);
}
public static function registerThisNode(): void
{
$node_id = config('settings.node.id');
Cluster::hset('nodes', $node_id, [
'type' => config('settings.node.type'),
'id' => $node_id,
'ip' => config('settings.node.ip'),
]);
2023-01-04 15:57:36 +00:00
Cluster::publish('node.ok');
2023-01-04 12:18:22 +00:00
}
}