laravel-wallet icon indicating copy to clipboard operation
laravel-wallet copied to clipboard

Almost always getting LockTimeoutException upgrading from transaction to atomic service

Open ibrunotome opened this issue 3 years ago • 8 comments

Describe your task Started to migrate to atomic because in the docs there is an advertise to replace transaction by it since 9.2.

The user request a withdrawal from his virtual wallet to his real bank account, the balance is updated and a fee is transferred to one wallet.

class WithdrawAction
{
    /**
     * @throws \Bavix\Wallet\Internal\Exceptions\ExceptionInterface
     */
    public function execute(User $user, array $input): UserWithdrawal
    {
        $workerWallet = $user->getWallet(BalanceAs::Worker->value);
        $profitWallet = profitWallet();

        return app(AtomicServiceInterface::class)->blocks([$workerWallet, $profitWallet], function () use ($user, $input, $workerWallet, $profitWallet) {
            $gateway = WithdrawalGateway::from($input['gateway']);

            /** @var UserWithdrawal $withdrawal */
            $withdrawal = $user->withdrawals()->create([
                'gateway'        => $gateway,
                'amount'         => $input['amount'],
               // ...
            ]);

            $this->transaction($workerWallet, $profitWallet, $withdrawal);
            $this->activityLog($user, $withdrawal);
            $this->notify($withdrawal);

            Cache::forget(CacheKey::LoggedInUser->value . ":{$withdrawal->user_id}");

            return $withdrawal;
        });
    }

    /**
     * @throws \Bavix\Wallet\Internal\Exceptions\ExceptionInterface
     */
    private function transaction(Wallet $workerWallet, Wallet $profitWallet, UserWithdrawal $withdrawal): void
    {
        $workerWallet
            ->withdrawFloat($withdrawal->received, [
                'description'          => "Withdraw #{$withdrawal->id}",
                'transactionable_type' => $withdrawal->getMorphClass(),
                'transactionable_id'   => $withdrawal->id,
            ]);

        $workerWallet
            ->transferFloat($profitWallet, $withdrawal->fee, [
                'description'          => "Withdraw #{$withdrawal->id} fees",
                'transactionable_type' => $withdrawal->getMorphClass(),
                'transactionable_id'   => $withdrawal->id,
            ]);
    }
}

In the admin panel, there is a nova action to confirm or deny the user withdrawal to his real bank account.

    public function handle(ActionFields $fields, Collection $models): array
    {
        DB::rollBack(0); // see https://github.com/bavix/laravel-wallet/issues/455

        /** @var \App\Models\UserWithdrawal $withdrawal */
        $withdrawal = $models->first();
        $withdrawal->support_notes = $fields->get('support_notes');

        $action = match ($fields->get('status')) {
            WithdrawalStatus::Confirmed->value => app(FromProcessingToConfirmedAction::class), // this will not make any wallet transaction
            WithdrawalStatus::Denied->value    => app(FromProcessingToDeniedAction::class), // this will transfer user funds back to his virtual wallet
        };

        $action->execute($withdrawal);

        return Action::redirect(config('nova.path') . '/resources/user-withdrawals');
    }

Since the FromProcessingToConfirmedAction doesn't touch wallet, I will paste just the FromProcessingToDeniedAction

class FromProcessingToDeniedAction
{
    /**
     * @throws \Bavix\Wallet\Internal\Exceptions\ExceptionInterface
     */
    public function execute(UserWithdrawal $withdrawal): void
    {
        $workerWallet = $withdrawal
            ->user
            ->getWallet(BalanceAs::Worker->value);

        $profitWallet = profitWallet();

        app(AtomicServiceInterface::class)->blocks([$workerWallet, $profitWallet], function () use ($withdrawal, $workerWallet, $profitWallet) {
            $withdrawal->status = WithdrawalStatus::Denied;
            $withdrawal->save();

            $this->transaction($workerWallet, $profitWallet, $withdrawal);
            $this->activityLog($withdrawal);

            $withdrawal->user->notify(new WithdrawalDeniedNotification(
                amount: $withdrawal->amount,
                gateway: $withdrawal->gateway->value,
                withdrawalTo: $withdrawal->to,
                reason: $withdrawal->support_notes
            ));
        });
    }

    /**
     * @throws \Bavix\Wallet\Internal\Exceptions\ExceptionInterface
     */
    private function transaction(Wallet $workerWallet, Wallet $profitWallet, UserWithdrawal $withdrawal): void
    {
        $workerWallet
            ->depositFloat($withdrawal->received, [
                'description'          => "Withdrawal #{$withdrawal->id} denied",
                'transactionable_type' => $withdrawal->getMorphClass(),
                'transactionable_id'   => $withdrawal->id,
            ]);

        $profitWallet
            ->forceTransferFloat($withdrawal->user->getWallet(BalanceAs::Worker->value), $withdrawal->calculateFee(), [
                'description'          => "Withdraw #{$withdrawal->id} fees refunded",
                'transactionable_type' => $withdrawal->getMorphClass(),
                'transactionable_id'   => $withdrawal->id,
            ]);
    }

To Reproduce Steps to reproduce the behavior:

Both actions randomly gives me LockTimeoutException, if I change the driver from redis to database, it works sometimes and them the exception comeback, I change from database to redis, the same behavior happens.

There is no other actions running in background, I'm in the localhost with no other users/jobs/schedules interacting with the wallet.

When using:

    'cache' => [
        'driver' => 'redis',
    ],

    /**
     * A system for dealing with race conditions.
     */
    'lock' => [
        'driver'  => 'database',
        'seconds' => 10,
    ],

the 10 seconds is not respected, the nova action gives me this instantly:

Screen Shot 2022-09-13 at 13 14 12

When using redis for lock driver, the 10 seconds is respected.

Trace Error

[previous exception] [object] (Illuminate\\Contracts\\Cache\\LockTimeoutException(code: 0):  at /var/www/vendor/laravel/framework/src/Illuminate/Cache/Lock.php:120)
[stacktrace]
#0 /var/www/vendor/bavix/laravel-wallet/src/Internal/Service/LockService.php(46): Illuminate\\Cache\\Lock->block(10, Object(Closure))
#1 /var/www/vendor/bavix/laravel-wallet/src/Internal/Decorator/StorageServiceLockDecorator.php(55): Bavix\\Wallet\\Internal\\Service\\LockService->block('ec6ed6fa-a050-4...', Object(Closure))
#2 /var/www/vendor/bavix/laravel-wallet/src/Services/BookkeeperService.php(59): Bavix\\Wallet\\Internal\\Decorator\\StorageServiceLockDecorator->increase('ec6ed6fa-a050-4...', '1000000000')
#3 /var/www/vendor/bavix/laravel-wallet/src/Services/RegulatorService.php(95): Bavix\\Wallet\\Services\\BookkeeperService->increase(Object(App\\Models\\Wallet), '1000000000')
#4 /var/www/vendor/bavix/laravel-wallet/src/Internal/Service/DatabaseService.php(60): Bavix\\Wallet\\Services\\RegulatorService->approve()
#5 /var/www/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php(30): Bavix\\Wallet\\Internal\\Service\\DatabaseService->Bavix\\Wallet\\Internal\\Service\\{closure}(Object(Illuminate\\Database\\PostgresConnection))
#6 /var/www/vendor/bavix/laravel-wallet/src/Internal/Service/DatabaseService.php(64): Illuminate\\Database\\Connection->transaction(Object(Closure))
#7 /var/www/vendor/bavix/laravel-wallet/src/Services/AtomicService.php(57): Bavix\\Wallet\\Internal\\Service\\DatabaseService->transaction(Object(Closure))
#8 /var/www/vendor/laravel/framework/src/Illuminate/Cache/Lock.php(126): Bavix\\Wallet\\Services\\AtomicService->Bavix\\Wallet\\Services\\{closure}()
#9 /var/www/vendor/bavix/laravel-wallet/src/Internal/Service/LockService.php(46): Illuminate\\Cache\\Lock->block(10, Object(Closure))
#10 /var/www/vendor/bavix/laravel-wallet/src/Services/AtomicService.php(61): Bavix\\Wallet\\Internal\\Service\\LockService->block('ec6ed6fa-a050-4...', Object(Closure))
#11 /var/www/vendor/laravel/framework/src/Illuminate/Cache/Lock.php(126): Bavix\\Wallet\\Services\\AtomicService->Bavix\\Wallet\\Services\\{closure}()
#12 /var/www/vendor/bavix/laravel-wallet/src/Internal/Service/LockService.php(46): Illuminate\\Cache\\Lock->block(10, Object(Closure))
#13 /var/www/vendor/bavix/laravel-wallet/src/Services/AtomicService.php(61): Bavix\\Wallet\\Internal\\Service\\LockService->block('f1f86d96-47d3-4...', Object(Closure))
#14 /var/www/vendor/bavix/laravel-wallet/src/Services/AtomicService.php(65): Bavix\\Wallet\\Services\\AtomicService->Bavix\\Wallet\\Services\\{closure}()
#15 /var/www/app/Actions/Settings/Withdrawals/Transitions/FromProcessingToDeniedAction.php(39): Bavix\\Wallet\\Services\\AtomicService->blocks(Array, Object(Closure))
#16 /var/www/app/Nova/Actions/ReviewWithdrawalNovaAction.php(75): App\\Actions\\Settings\\Withdrawals\\Transitions\\FromProcessingToDeniedAction->execute(Object(App\\Models\\UserWithdrawal))
#17 /var/www/vendor/laravel/nova/src/Actions/DispatchAction.php(247): App\\Nova\\Actions\\ReviewWithdrawalNovaAction->handle(Object(Laravel\\Nova\\Fields\\ActionFields), Object(Laravel\\Nova\\Actions\\ActionModelCollection))
#18 /var/www/vendor/laravel/nova/src/Actions/Transaction.php(27): Laravel\\Nova\\Actions\\DispatchAction->Laravel\\Nova\\Actions\\{closure}('9741a832-337a-4...')
#19 /var/www/vendor/laravel/nova/src/Actions/DispatchAction.php(252): Laravel\\Nova\\Actions\\Transaction::run(Object(Closure), Object(Closure))
#20 /var/www/vendor/laravel/nova/src/Actions/DispatchAction.php(224): Laravel\\Nova\\Actions\\DispatchAction->dispatchSynchronouslyForCollection('handle', Object(Laravel\\Nova\\Actions\\ActionModelCollection))
#21 /var/www/vendor/laravel/nova/src/Actions/DispatchAction.php(177): Laravel\\Nova\\Actions\\DispatchAction->forModels('handle', Object(Laravel\\Nova\\Actions\\ActionModelCollection))
#22 /var/www/vendor/laravel/nova/src/Http/Requests/ActionRequest.php(97): Laravel\\Nova\\Actions\\DispatchAction->Laravel\\Nova\\Actions\\{closure}(Object(Laravel\\Nova\\Actions\\ActionModelCollection))
#23 /var/www/vendor/laravel/framework/src/Illuminate/Collections/Traits/EnumeratesValues.php(262): Laravel\\Nova\\Http\\Requests\\ActionRequest->Laravel\\Nova\\Http\\Requests\\{closure}(Object(Illuminate\\Support\\LazyCollection), 0)
#24 /var/www/vendor/laravel/nova/src/Http/Requests/ActionRequest.php(98): Illuminate\\Support\\LazyCollection->each(Object(Closure))
#25 /var/www/vendor/laravel/nova/src/Actions/DispatchAction.php(178): Laravel\\Nova\\Http\\Requests\\ActionRequest->chunks(200, Object(Closure))
#26 /var/www/vendor/laravel/framework/src/Illuminate/Support/helpers.php(418): Laravel\\Nova\\Actions\\DispatchAction->Laravel\\Nova\\Actions\\{closure}(Object(Laravel\\Nova\\Actions\\Response))
#27 /var/www/vendor/laravel/nova/src/Actions/DispatchAction.php(116): with(Object(Laravel\\Nova\\Actions\\Response), Object(Closure))
#28 /var/www/vendor/laravel/nova/src/Actions/Action.php(309): Laravel\\Nova\\Actions\\DispatchAction->dispatch()
#29 /var/www/vendor/laravel/nova/src/Http/Controllers/ActionController.php(58): Laravel\\Nova\\Actions\\Action->handleRequest(Object(Laravel\\Nova\\Http\\Requests\\ActionRequest))
#30 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): Laravel\\Nova\\Http\\Controllers\\ActionController->store(Object(Laravel\\Nova\\Http\\Requests\\ActionRequest), 'user-withdrawal...')
#31 /var/www/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(45): Illuminate\\Routing\\Controller->callAction('store', Array)
#32 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php(261): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(Laravel\\Nova\\Http\\Controllers\\ActionController), 'store')
#33 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php(204): Illuminate\\Routing\\Route->runController()
#34 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(725): Illuminate\\Routing\\Route->run()
#35 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#36 /var/www/vendor/laravel/nova/src/Http/Middleware/Authorize.php(18): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#37 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Laravel\\Nova\\Http\\Middleware\\Authorize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#38 /var/www/vendor/laravel/nova/src/Http/Middleware/BootTools.php(20): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#39 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Laravel\\Nova\\Http\\Middleware\\BootTools->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#40 /var/www/vendor/laravel/nova/src/Http/Middleware/DispatchServingNovaEvent.php(24): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#41 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Laravel\\Nova\\Http\\Middleware\\DispatchServingNovaEvent->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#42 /var/www/vendor/inertiajs/inertia-laravel/src/Middleware.php(92): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#43 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Inertia\\Middleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#44 /var/www/vendor/inertiajs/inertia-laravel/src/Middleware.php(92): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#45 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Inertia\\Middleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#46 /var/www/app/Http/Middleware/AddResponseHeaders.php(12): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#47 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): App\\Http\\Middleware\\AddResponseHeaders->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#48 /var/www/app/Http/Middleware/CheckFirebaseToken.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#49 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): App\\Http\\Middleware\\CheckFirebaseToken->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#50 /var/www/app/Http/Middleware/CheckReferral.php(24): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#51 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): App\\Http\\Middleware\\CheckReferral->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#52 /var/www/app/Http/Middleware/RedirectIfBlacklisted.php(22): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#53 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): App\\Http\\Middleware\\RedirectIfBlacklisted->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#54 /var/www/app/Http/Middleware/RedirectIfAccountDeleted.php(30): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#55 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): App\\Http\\Middleware\\RedirectIfAccountDeleted->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#56 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#57 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#58 /var/www/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php(44): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#59 /var/www/vendor/laravel/nova/src/Http/Middleware/Authenticate.php(31): Illuminate\\Auth\\Middleware\\Authenticate->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#60 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Laravel\\Nova\\Http\\Middleware\\Authenticate->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#61 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(78): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#62 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#63 /var/www/app/Http/Middleware/SetLocale.php(42): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#64 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): App\\Http\\Middleware\\SetLocale->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#65 /var/www/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#66 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#67 /var/www/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#68 /var/www/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest(Object(Illuminate\\Http\\Request), Object(Illuminate\\Session\\Store), Object(Closure))
#69 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Session\\Middleware\\StartSession->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#70 /var/www/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#71 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#72 /var/www/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#73 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#74 /var/www/vendor/inspector-apm/inspector-laravel/src/Middleware/WebRequestMonitoring.php(35): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#75 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Inspector\\Laravel\\Middleware\\WebRequestMonitoring->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#76 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#77 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(726): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#78 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(703): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))
#79 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(667): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route))
#80 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(656): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))
#81 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(167): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))
#82 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))
#83 /var/www/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Http/SetRequestIpMiddleware.php(45): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#84 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Sentry\\Laravel\\Http\\SetRequestIpMiddleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#85 /var/www/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Http/SetRequestMiddleware.php(42): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#86 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Sentry\\Laravel\\Http\\SetRequestMiddleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#87 /var/www/vendor/laravel/nova/src/Http/Middleware/ServeNova.php(23): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#88 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Laravel\\Nova\\Http\\Middleware\\ServeNova->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#89 /var/www/vendor/barryvdh/laravel-debugbar/src/Middleware/InjectDebugbar.php(59): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#90 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Barryvdh\\Debugbar\\Middleware\\InjectDebugbar->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#91 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#92 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#93 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#94 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#95 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#96 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#97 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#98 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#99 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#100 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#101 /var/www/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#102 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Http\\Middleware\\HandleCors->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#103 /var/www/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(39): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#104 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\\Http\\Middleware\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#105 /var/www/vendor/code-distortion/adapt/src/Laravel/Middleware/RemoteShareMiddleware.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#106 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): CodeDistortion\\Adapt\\Laravel\\Middleware\\RemoteShareMiddleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#107 /var/www/vendor/code-distortion/adapt/src/Laravel/Middleware/ReplaceResponseWithRemoteBuildResponseMiddleware.php(33): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#108 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): CodeDistortion\\Adapt\\Laravel\\Middleware\\ReplaceResponseWithRemoteBuildResponseMiddleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#109 /var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#110 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(142): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#111 /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(111): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
#112 /var/www/vendor/laravel/octane/src/ApplicationGateway.php(36): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
#113 /var/www/vendor/laravel/octane/src/Worker.php(92): Laravel\\Octane\\ApplicationGateway->handle(Object(Illuminate\\Http\\Request))
#114 /var/www/vendor/laravel/octane/bin/swoole-server(118): Laravel\\Octane\\Worker->handle(Object(Illuminate\\Http\\Request), Object(Laravel\\Octane\\RequestContext))
#115 [internal function]: {closure}(Object(Swoole\\Http\\Request), Object(Swoole\\Http\\Response))
#116 /var/www/vendor/laravel/octane/bin/swoole-server(164): Swoole\\Server->start()
#117 {main}
"}

Server:

  • php version: 8.1
  • database: postgres 14.0
  • wallet version 9.3
  • cache lock: redis
  • cache wallets: redis

ibrunotome avatar Sep 13 '22 15:09 ibrunotome

@ibrunotome I will try to reproduce the case. Thank you.

rez1dent3 avatar Sep 13 '22 16:09 rez1dent3

@ibrunotome It looks like your problem is related to laravel octane. At the moment, I have not tested the wallet with roadrunner, swoole, open swoole and fibers inside octane. I think that the lock is not removed there and the application crashes by timeout.

rez1dent3 avatar Sep 13 '22 16:09 rez1dent3

@ibrunotome It looks like your problem is related to laravel octane. At the moment, I have not tested the wallet with roadrunner, swoole, open swoole and fibers inside octane. I think that the lock is not removed there and the application crashes by timeout.

I forgot to mention that I always was using octane, glad to see that you saw that in the stacktrace 🙌

ibrunotome avatar Sep 13 '22 19:09 ibrunotome

Hi, can I help with something related to test it with octane?

ibrunotome avatar Sep 20 '22 01:09 ibrunotome

Hi, @ibrunotome . Now it's busy at work. Didn't get to check. I'll try to take a look over the weekend.

rez1dent3 avatar Sep 20 '22 16:09 rez1dent3

It is necessary to rewrite part of the package under octane, and this is labor-intensive. At the moment, it is not safe to use even older versions with octane. I will try to add octane support in the future, but there is no support right now.

@ibrunotome There are too many problems with octane. Postponed this idea.

rez1dent3 avatar Sep 21 '22 20:09 rez1dent3

Me using it in production right now:

Is there anything that can help to erase the state to be safe (even if the impact in performance is huge) using the octane listeners?

Screen Shot 2022-09-21 at 17 47 05

Let me know if I can help with anything.

ibrunotome avatar Sep 21 '22 20:09 ibrunotome

The case is easy to reproduce, there are no problems with this. I will soon return to trying to screw the octane. Try to fix the problem yourself, maybe you can do it faster.

But I would not recommend using previous versions in production. I ran our race condition tests in 9.0+ octane and the problem is there.

rez1dent3 avatar Sep 22 '22 05:09 rez1dent3

@ibrunotome tag 9.4.0

rez1dent3 avatar Sep 29 '22 15:09 rez1dent3