From 6ba03f82842f9f86467aa52146dddae6b89110d4 Mon Sep 17 00:00:00 2001 From: Oleksii Yatsenko Date: Sun, 11 Sep 2022 10:44:29 +0100 Subject: [PATCH] Add caching experiment users --- .../Console/RunUsersExperimentsIndexer.php | 38 +++++++++++++++++++ .../Controllers/ExperimentsController.php | 15 +++++++- .../AllUsersExperimentsHotStorageManager.php | 30 +++++++++++++++ .../AbRouter/Managers/HotKvStorageManager.php | 14 +++++++ .../Providers/AbRouterServiceProvider.php | 10 +++-- Modules/AbRouter/Providers/KernelProvider.php | 21 ++++++++++ ...llUsersExperimentsHotStorageRepository.php | 32 ++++++++++++++++ .../Repositories/HotKvStorageRepository.php | 18 +++++++++ .../Repositories/Users/UsersRepository.php | 26 +++++++++++++ .../ProcessAllUsersExperimentsService.php | 30 +++++++++++++++ .../ProcessUsersExperimentsService.php | 35 +++++++++++++++++ .../AllUsersExperimentsTransformer.php | 2 +- .../HotKvStorageKeysTransformer.php | 11 ++++++ 13 files changed, 277 insertions(+), 5 deletions(-) create mode 100644 Modules/AbRouter/Console/RunUsersExperimentsIndexer.php create mode 100644 Modules/AbRouter/Managers/AllUsersExperimentsHotStorageManager.php create mode 100644 Modules/AbRouter/Managers/HotKvStorageManager.php create mode 100644 Modules/AbRouter/Providers/KernelProvider.php create mode 100644 Modules/AbRouter/Repositories/AllUsersExperimentsHotStorageRepository.php create mode 100644 Modules/AbRouter/Repositories/HotKvStorageRepository.php create mode 100644 Modules/AbRouter/Repositories/Users/UsersRepository.php create mode 100644 Modules/AbRouter/Services/UsersExperiments/ProcessAllUsersExperimentsService.php create mode 100644 Modules/AbRouter/Services/UsersExperiments/ProcessUsersExperimentsService.php create mode 100644 Modules/AbRouter/Transformers/HotKvStorageKeysTransformer.php diff --git a/Modules/AbRouter/Console/RunUsersExperimentsIndexer.php b/Modules/AbRouter/Console/RunUsersExperimentsIndexer.php new file mode 100644 index 0000000..c3f612c --- /dev/null +++ b/Modules/AbRouter/Console/RunUsersExperimentsIndexer.php @@ -0,0 +1,38 @@ +make(ProcessAllUsersExperimentsService::class); + $processAllUsersExperiments->processAll(); + } +} diff --git a/Modules/AbRouter/Http/Controllers/ExperimentsController.php b/Modules/AbRouter/Http/Controllers/ExperimentsController.php index 5d63638..00dd1b0 100644 --- a/Modules/AbRouter/Http/Controllers/ExperimentsController.php +++ b/Modules/AbRouter/Http/Controllers/ExperimentsController.php @@ -3,6 +3,7 @@ namespace Modules\AbRouter\Http\Controllers; use AbRouter\JsonApiFormatter\DataSource\DataProviders\SimpleDataProvider; +use Illuminate\Http\Response; use Laravel\Passport\Token; use Illuminate\Http\Request; use Illuminate\Routing\Controller; @@ -17,6 +18,7 @@ use Modules\AbRouter\Http\Transformers\Experiments\SimpleRunTransformer; use Modules\AbRouter\Http\Transformers\Experiments\UserExperimentsTransformer; use Modules\AbRouter\Models\Experiments\Experiment; +use Modules\AbRouter\Repositories\AllUsersExperimentsHotStorageRepository; use Modules\AbRouter\Repositories\Experiments\ExperimentBranchUserRepository; use Modules\AbRouter\Repositories\Experiments\ExperimentUsersRepository; use Modules\AbRouter\Services\Experiment\ExperimentService; @@ -157,9 +159,20 @@ public function deleteUserFromExperiment( public function allUsersExperiments( ExperimentUsersRepository $repository, AuthDecorator $authDecorator, - AllUsersExperimentsTransformer $allUsersExperimentsTransformer + AllUsersExperimentsTransformer $allUsersExperimentsTransformer, + AllUsersExperimentsHotStorageRepository $allUsersExperimentsHotStorageRepository ) { $ownerId = $authDecorator->get()->getId(); + if ($allUsersExperimentsHotStorageRepository->get($ownerId)) { + return response([ + 'status' => false, + 'message' => 'Calculating, try in 5 minutes', + 'data' => [ + 'retryIn' => 300, + ], + Response::HTTP_PROCESSING + ]); + } return $allUsersExperimentsTransformer->getAllUsersExperiments( $repository->getAllUsersExperiments($ownerId) diff --git a/Modules/AbRouter/Managers/AllUsersExperimentsHotStorageManager.php b/Modules/AbRouter/Managers/AllUsersExperimentsHotStorageManager.php new file mode 100644 index 0000000..bbbbdd4 --- /dev/null +++ b/Modules/AbRouter/Managers/AllUsersExperimentsHotStorageManager.php @@ -0,0 +1,30 @@ +hotKvStorageManager = $hotKvStorageManager; + $this->hotKvStorageKeysTransformer = $hotKvStorageKeysTransformer; + } + + public function store(int $ownerId, Collection $collection) + { + $this->hotKvStorageManager->store( + $this->hotKvStorageKeysTransformer->getAllUsersKey($ownerId), + serialize($collection) + ); + } +} diff --git a/Modules/AbRouter/Managers/HotKvStorageManager.php b/Modules/AbRouter/Managers/HotKvStorageManager.php new file mode 100644 index 0000000..62208d8 --- /dev/null +++ b/Modules/AbRouter/Managers/HotKvStorageManager.php @@ -0,0 +1,14 @@ +client()->set($key, $data); + } +} diff --git a/Modules/AbRouter/Providers/AbRouterServiceProvider.php b/Modules/AbRouter/Providers/AbRouterServiceProvider.php index 885bf3d..99efe58 100644 --- a/Modules/AbRouter/Providers/AbRouterServiceProvider.php +++ b/Modules/AbRouter/Providers/AbRouterServiceProvider.php @@ -5,7 +5,10 @@ use Illuminate\Support\Facades\View; use Illuminate\Support\ServiceProvider; use Illuminate\Database\Eloquent\Factory; +use Modules\AbRouter\Console\CreateDatabase; +use Modules\AbRouter\Console\DropDatabase; use Modules\AbRouter\Console\FillOwnerIdExperimentUserBranches; +use Modules\AbRouter\Console\MigrateTemporaryUser; class AbRouterServiceProvider extends ServiceProvider { @@ -21,9 +24,9 @@ public function boot() $this->registerConfig(); $this->registerViews(); $this->registerFactories(); - $this->commands([\Modules\AbRouter\Console\CreateDatabase::class]); - $this->commands([\Modules\AbRouter\Console\DropDatabase::class]); - $this->commands([\Modules\AbRouter\Console\MigrateTemporaryUser::class]); + $this->commands([CreateDatabase::class]); + $this->commands([DropDatabase::class]); + $this->commands([MigrateTemporaryUser::class]); $this->commands([FillOwnerIdExperimentUserBranches::class]); $this->loadMigrationsFrom(module_path('AbRouter', 'Database/Migrations')); @@ -37,6 +40,7 @@ public function boot() public function register() { $this->app->register(RouteServiceProvider::class); + $this->app->register(KernelProvider::class); } /** diff --git a/Modules/AbRouter/Providers/KernelProvider.php b/Modules/AbRouter/Providers/KernelProvider.php new file mode 100644 index 0000000..52f362a --- /dev/null +++ b/Modules/AbRouter/Providers/KernelProvider.php @@ -0,0 +1,21 @@ +call(function () { + /** + * @var ProcessAllUsersExperimentsService $processAllUsersExperiments + */ + $processAllUsersExperiments = app()->make(ProcessAllUsersExperimentsService::class); + $processAllUsersExperiments->processAll(); + })->everyThirtyMinutes(); + } +} diff --git a/Modules/AbRouter/Repositories/AllUsersExperimentsHotStorageRepository.php b/Modules/AbRouter/Repositories/AllUsersExperimentsHotStorageRepository.php new file mode 100644 index 0000000..6b852b6 --- /dev/null +++ b/Modules/AbRouter/Repositories/AllUsersExperimentsHotStorageRepository.php @@ -0,0 +1,32 @@ +hotKvStorageRepository = $hotKvStorageRepository; + $this->hotKvStorageKeysTransformer = $hotKvStorageKeysTransformer; + } + + public function get(int $ownerId): ?Collection + { + $data = $this->hotKvStorageRepository->get($this->hotKvStorageKeysTransformer->getAllUsersKey($ownerId)); + if (empty($data)) { + return null; + } + + return unserialize($data); + } +} diff --git a/Modules/AbRouter/Repositories/HotKvStorageRepository.php b/Modules/AbRouter/Repositories/HotKvStorageRepository.php new file mode 100644 index 0000000..c6070e8 --- /dev/null +++ b/Modules/AbRouter/Repositories/HotKvStorageRepository.php @@ -0,0 +1,18 @@ +client()->get($key); + } +} diff --git a/Modules/AbRouter/Repositories/Users/UsersRepository.php b/Modules/AbRouter/Repositories/Users/UsersRepository.php new file mode 100644 index 0000000..8c0b299 --- /dev/null +++ b/Modules/AbRouter/Repositories/Users/UsersRepository.php @@ -0,0 +1,26 @@ +query() + ->select('users.*') + ->join('experiments', 'users.id', '=', 'experiments.owner_id') + ->whereNotNull('experiments.id') + ->get(); + } + + protected function getModel() + { + return new User(); + } +} diff --git a/Modules/AbRouter/Services/UsersExperiments/ProcessAllUsersExperimentsService.php b/Modules/AbRouter/Services/UsersExperiments/ProcessAllUsersExperimentsService.php new file mode 100644 index 0000000..1abe220 --- /dev/null +++ b/Modules/AbRouter/Services/UsersExperiments/ProcessAllUsersExperimentsService.php @@ -0,0 +1,30 @@ +processUsersExperimentsService = $processUsersExperimentsService; + $this->usersRepository = $usersRepository; + } + + public function processAll(): void + { + $allUsers = $this->usersRepository->getUsersWithExperimentExists(); + $allUsers->each(function (User $user) { + $this->processUsersExperimentsService->processByOwnerId($user->id); + }); + } +} diff --git a/Modules/AbRouter/Services/UsersExperiments/ProcessUsersExperimentsService.php b/Modules/AbRouter/Services/UsersExperiments/ProcessUsersExperimentsService.php new file mode 100644 index 0000000..39c8506 --- /dev/null +++ b/Modules/AbRouter/Services/UsersExperiments/ProcessUsersExperimentsService.php @@ -0,0 +1,35 @@ +experimentUsersRepository = $experimentUsersRepository; + $this->allUsersExperimentsTransformer = $allUsersExperimentsTransformer; + $this->allUsersExperimentsHotStorageManager = $allUsersExperimentsHotStorageManager; + } + + public function processByOwnerId(int $ownerId): void + { + $allUsersExperiments = $this->allUsersExperimentsTransformer->getAllUsersExperiments( + $this->experimentUsersRepository->getAllUsersExperiments($ownerId) + ); + $this->allUsersExperimentsHotStorageManager->store($ownerId, collect($allUsersExperiments)); + } +} diff --git a/Modules/AbRouter/Transformers/AllUsersExperimentsTransformer.php b/Modules/AbRouter/Transformers/AllUsersExperimentsTransformer.php index 85e6dea..a8223a1 100644 --- a/Modules/AbRouter/Transformers/AllUsersExperimentsTransformer.php +++ b/Modules/AbRouter/Transformers/AllUsersExperimentsTransformer.php @@ -23,7 +23,7 @@ public function getAllUsersExperiments(Collection $usersExperiments): array return $allUsersExperiments; } - public function getExperiments(Collection $experimentUsers): array + private function getExperiments(Collection $experimentUsers): array { $experiments = []; diff --git a/Modules/AbRouter/Transformers/HotKvStorageKeysTransformer.php b/Modules/AbRouter/Transformers/HotKvStorageKeysTransformer.php new file mode 100644 index 0000000..3a3aba2 --- /dev/null +++ b/Modules/AbRouter/Transformers/HotKvStorageKeysTransformer.php @@ -0,0 +1,11 @@ +