diff --git a/app/Jobs/FireEvent.php b/app/Jobs/FireEvent.php new file mode 100644 index 00000000..2503abc2 --- /dev/null +++ b/app/Jobs/FireEvent.php @@ -0,0 +1,56 @@ +name; + $idKey = $this->idKey; + $idKeyOld = $this->idKeyOld; + $log = "Job FireEvent, name: $name, idKey: $idKey, idKeyOld: $idKeyOld"; + do_log("$log, begin ..."); + if (isset(ModelEventEnum::$eventMaps[$name])) { + $eventName = ModelEventEnum::$eventMaps[$name]['event']; + $modelClassName = ModelEventEnum::$eventMaps[$name]['model']; + $modelBasic = new $modelClassName(); + $modelData = unserialize(NexusDB::cache_get($idKey)); + $useArray = str_ends_with($name, '_deleted'); + $model = call_user_func_array([$modelBasic, "newInstance"], [$modelData, true]); + //由于 id 不属于 fillable,初始化新对象时是没有值的 + $model->id = $modelData['id']; + $params = [$useArray ? $modelData: $model]; + if ($idKeyOld) { + $modelOldData = unserialize(NexusDB::cache_get($idKeyOld)); + $modelOld = call_user_func_array([$modelBasic, "newInstance"], [$modelOldData, true]); + $modelOld->id = $modelOldData['id']; + $params[] = $useArray ? $modelOldData: $modelOld; + } + $result = call_user_func_array([$eventName, "dispatch"], $params); + $log .= ", success call dispatch, result: " . var_export($result, true); + publish_model_event($name, $model->id); + } else { + $log .= ", no event match this name"; + } + do_log($log); + } +} diff --git a/include/globalfunctions.php b/include/globalfunctions.php index 0bf24449..75ec3e95 100644 --- a/include/globalfunctions.php +++ b/include/globalfunctions.php @@ -1345,7 +1345,8 @@ function fire_event(string $name, \Illuminate\Database\Eloquent\Model $model, ?\ $idKeyOld = $prefix . \Illuminate\Support\Str::random(); \Nexus\Database\NexusDB::cache_put($idKeyOld, serialize($oldModel->toArray()), 3600*24*30); } - executeCommand("event:fire --name=$name --idKey=$idKey --idKeyOld=$idKeyOld", "string", true, false); +// executeCommand("event:fire --name=$name --idKey=$idKey --idKeyOld=$idKeyOld", "string", true, false); + \Nexus\Nexus::dispatchQueueJob(new \App\Jobs\FireEvent($name, $idKey, $idKeyOld)); } else { $eventClass = \App\Enums\ModelEventEnum::$eventMaps[$name]['event']; if (str_ends_with($name, '_deleted')) { diff --git a/nexus/Database/NexusDB.php b/nexus/Database/NexusDB.php index 7a044641..05ec8600 100644 --- a/nexus/Database/NexusDB.php +++ b/nexus/Database/NexusDB.php @@ -4,6 +4,7 @@ namespace Nexus\Database; use App\Models\OauthClient; use App\Models\PersonalAccessToken; +use Illuminate\Container\Container; use Illuminate\Support\Facades\Schema; use Illuminate\Database\Capsule\Manager as Capsule; use Illuminate\Database\Query\Expression; @@ -257,7 +258,7 @@ class NexusDB public static function bootEloquent(array $config) { - $capsule = new Capsule; + $capsule = new Capsule(Container::getInstance()); $connectionName = self::ELOQUENT_CONNECTION_NAME; $capsule->addConnection($config, $connectionName); $capsule->setAsGlobal(); diff --git a/nexus/Nexus.php b/nexus/Nexus.php index 7d5fc297..d29b4be5 100644 --- a/nexus/Nexus.php +++ b/nexus/Nexus.php @@ -2,9 +2,11 @@ namespace Nexus; use App\Http\Middleware\Locale; +use Illuminate\Container\Container; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Queue\Capsule\Manager; +use Illuminate\Redis\RedisManager; use Illuminate\Support\Arr; -use Illuminate\Support\Str; -use Nexus\Plugin\Hook; use Nexus\Translation\NexusTranslator; final class Nexus @@ -33,6 +35,10 @@ final class Nexus private static ?NexusTranslator $translator = null; + private static ?Manager $queueManager = null; + + const QUEUE_CONNECTION_NAME = 'my_queue_connection'; + const PLATFORM_USER = 'user'; const PLATFORM_ADMIN = 'admin'; const PLATFORM_TRACKER = 'tracker'; @@ -384,5 +390,39 @@ final class Nexus return self::$translator; } + private static function getQueueManager(): Manager + { + if (is_null(self::$queueManager)) { + $container = Container::getInstance(); + $redisConfig = nexus_config('nexus.redis'); + $redisConnectionName = "my_redis_connection"; + $container->singleton('redis', function ($app) use ($redisConfig, $redisConnectionName) { + $redisDriver = "phpredis"; + // 这里的配置应该匹配 redis.php 配置文件中的 default 连接 + $connectionConfig = [ + 'client' => $redisDriver, + $redisConnectionName => $redisConfig + ]; + return new RedisManager($app, $redisDriver, $connectionConfig); + }); + $queueManager = new Manager($container); + $queueManager->addConnection([ + 'driver' => 'redis', + 'host' => $redisConfig['host'], + 'password' => $redisConfig['password'], + 'queue' => 'nexus_queue', // 队列名称 + 'connection' => $redisConnectionName, // Redis 连接名称,类似注册的 'redis' 服务中的 'default' + ], self::QUEUE_CONNECTION_NAME); // 将这个 queue 连接起个不一样的名字 + $queueManager->setAsGlobal(); + self::$queueManager = $queueManager; + } + return self::$queueManager; + } + + public static function dispatchQueueJob(ShouldQueue $job): void + { + self::getQueueManager()->connection(self::QUEUE_CONNECTION_NAME)->push($job); + } + }