-
-
Notifications
You must be signed in to change notification settings - Fork 240
feat: fallback cache and lock driver #546
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hello. |
And here is the framework layer. |
Hi @rez1dent3, thank you for the quick support. But, I didn't said it's a package issue, I made a feature request. Would it possible to make a change to achieve this behavior? |
No. This is the infrastructure layer. The code shouldn't work in that case. Your cache should be behind a balancer (for example, haproxy) and monitor it. In case of problems, change the master. I would consider sentinel if I were you. |
For example, if you solve this with code, then you need to maintain data consistency in the failback storage. And this is already overhead. |
If you are going to solve a problem with code, you will most likely have a race condition. Sample packages can be found in packagist. Someone solved a similar problem: https://github.com/mathieu-bour/laravel-cache-fallback PS, I highly recommend using cluster solutions. |
Thank you for all the links/recommendations. |
@ibrunotome You are welcome.
Don't overuse interfaces too much, you need to have a deep understanding of working with the state. Read #412 |
laravel-wallet/tests/Units/Domain/StateTest.php Lines 80 to 98 in 7a30789
|
@ibrunotome The last thing I remembered, you can pull the balance from the database directly. It is clear that there may be data lagging a bit (race condition). laravel-wallet/src/Models/Wallet.php Line 122 in c4e5d69
|
@rez1dent3 sometimes I'm getting exceptions with no messages, have you seem that before? the code is a transaction with 1 to 3 possible transactions, ex: app(DatabaseServiceInterface::class)->transaction(function () use ($workContract) {
$this->transaction($workContract); // transaction that always occurs
$this->distributeAffiliateEarnings($workContract); // transaction that conditionally occurs
$this->distributeBonus($workContract); // transaction that conditionally occurs
}); |
@ibrunotome Example: try {
app(DatabaseServiceInterface::class)->transaction(function () use ($workContract) {
$this->transaction($workContract); // transaction that always occurs
$this->distributeAffiliateEarnings($workContract); // transaction that conditionally occurs
$this->distributeBonus($workContract); // transaction that conditionally occurs
});
} catch (\Throwable $t) {
dd($throwable->getPrevious());
} |
It was a LockTimeoutException, who doesn't has messages. (so even with ->getPrevious() there wasn't messages) I switched the lock driver to database, by now these are my settings: Facing issues in production that I can't simulate in local or testing environment, maybe because i'm using redis in https://cloud.google.com/memorystore, and, in all other environments a simple |
There are two options here:
here you need to profile. |
Is your feature request related to a problem? Please describe.
Recently, I got almost 100 concurrent requests to debit balance from one wallet via api, and I got a redis exception "could not acquire lock"
Describe the solution you'd like
Read data directly from database when could not acquire lock (and update the state in redis in the next request)
Describe alternatives you've considered
Tried other cache drivers, but the only centralized is redis, array driver for example would give two different results if you access balance in a http container vs a container for queues for example.
P.S: I would put a warning about that non centralized cache drivers in the docs.
The text was updated successfully, but these errors were encountered: