Skip to content

[question] Balance cache #413

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

Closed
mattvb91 opened this issue Nov 30, 2021 · 2 comments
Closed

[question] Balance cache #413

mattvb91 opened this issue Nov 30, 2021 · 2 comments
Assignees
Labels
good issue Good for newcomers question Further information is requested Stale

Comments

@mattvb91
Copy link

mattvb91 commented Nov 30, 2021

Just wondering about the correct procedure here.

I had the cache driver set to array for initial testing and ended up getting wrong balances and deposits during transfers due to me running a job inside its own docker container (which would have kept its own balance cache) and my seperate php server (Which again would have kept its own balance cache).

Changing the cache driver to redis which both containers share has fixed the issue which makes sense but it has made me a bit paranoid. Is it possible to just deactivate the cache completely and always read the db values?

Should I be using wallet->refreshBalance() all the time just incase before making a transaction?

EDIT: just noticed in 7.0.0 release the refresh command was removed.

@rez1dent3
Copy link
Member

rez1dent3 commented Nov 30, 2021

Hello.

EDIT: just noticed in 7.0.0 release the refresh command was removed.

Not certainly in that way. It has been moved to a separate repository. Use the command only as a last resort.
https://github.com/bavix/laravel-wallet-warmup

I had the cache driver set to array for initial testing and ended up getting wrong balances and deposits during transfers due to me running a job inside its own docker container (which would have kept its own balance cache) and my seperate php server (Which again would have kept its own balance cache).

If the array driver is enabled, then assume that you have no atomicity at all. If there are two requests, they will both be executed.

If you configure a lock service, then such requests will go to the "queue". I recommend everyone to use redis because it is single threaded and guarantees data atomicity.

Is it possible to just deactivate the cache completely and always read the db values?

You can, but in this case you will have to inherit from the Wallet model and override the getBalanceAttribute method.
I do not recommend doing this, because the following case may turn out.

$wallet->balanceInt; // 1000
$transaction = $wallet->withdraw(1000, null, false); // not confirm. 
// we checked that there is money, created an unconfirmed transaction

$wallet->balanceInt; // 1000

// at that moment another request came and all the money was debited from the account
// any logic...

$wallet->safeConfirm($transaction); // true.. 
$wallet->balanceInt; // -1000

This is an example why I am not using a column from a database.

Let's take a look at another case?

$wallet->refresh(); // Just in case
$wallet->balanceInt; // 1000
// Another request has already charged your money. But the model will not know about it. balance=0
$wallet->withdraw(1000); // balance=-1000

I remembered another case.

$wallet1 = $user->wallet;
$wallet2 = Wallet::query()->find($wallet1->getKey());
assert($wallet1->getKey() === $wallet2->getKey()); // true
assert($wallet1 !== $wallet2); // true

$wallet1->balanceInt; // 0
$wallet2->deposit(100);

$wallet1->balanceInt; // 100
$wallet2->balanceInt; // 100

If you do not take data from the database, then you can safely refer to any model. And it, in turn, will pull the necessary data from the cache. Thus, if suddenly you are accessing not the same object, the balance data for them is the same.

Should I be using wallet->refreshBalance() all the time just incase before making a transaction?

No, this is an extreme measure. If you have a lot of transactions in the table, then this query can be fatal for the sale. The cache contains up-to-date information.

Version 7.1 is currently in development, which will add support for transactions between the cache service and the database. More details here #412

@rez1dent3 rez1dent3 self-assigned this Nov 30, 2021
@rez1dent3 rez1dent3 added good issue Good for newcomers question Further information is requested labels Nov 30, 2021
@github-actions
Copy link

This issue is stale because it has been open 21 days with no activity.

@github-actions github-actions bot added the Stale label Dec 22, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 4, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
good issue Good for newcomers question Further information is requested Stale
Projects
None yet
Development

No branches or pull requests

2 participants