Skip to content

Commit 4105ab0

Browse files
committed
laravel octane init
1 parent aa0ccae commit 4105ab0

File tree

6 files changed

+106
-82
lines changed

6 files changed

+106
-82
lines changed

src/Internal/Service/LockService.php

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,23 @@
1212

1313
final class LockService implements LockServiceInterface
1414
{
15-
private const PREFIX = 'wallet_lock::';
15+
private const LOCK_KEY = 'wallet_lock::';
1616

17-
/**
18-
* @var array<string, bool>
19-
*/
20-
private array $lockedKeys = [];
17+
private const INNER_KEYS = 'inner_keys::';
18+
19+
private ?LockProvider $lockProvider = null;
20+
21+
private CacheRepository $lockedKeys;
2122

2223
private CacheRepository $cache;
2324

2425
private int $seconds;
2526

2627
public function __construct(CacheFactory $cacheFactory)
2728
{
28-
$this->seconds = (int) config('wallet.lock.seconds', 1);
2929
$this->cache = $cacheFactory->store(config('wallet.lock.driver', 'array'));
30+
$this->seconds = (int) config('wallet.lock.seconds', 1);
31+
$this->lockedKeys = $cacheFactory->store('array');
3032
}
3133

3234
/**
@@ -38,21 +40,20 @@ public function block(string $key, callable $callback): mixed
3840
return $callback();
3941
}
4042

41-
$this->lockedKeys[$key] = true;
43+
$lock = $this->getLockProvider()
44+
->lock(self::LOCK_KEY . $key, $this->seconds);
45+
$this->lockedKeys->put(self::INNER_KEYS . $key, true, $this->seconds);
4246

4347
try {
44-
return $this->getLockProvider()
45-
->lock(self::PREFIX . $key)
46-
->block($this->seconds, $callback)
47-
;
48+
return $callback();
4849
} finally {
49-
unset($this->lockedKeys[$key]);
50+
$this->lockedKeys->delete(self::INNER_KEYS . $key);
5051
}
5152
}
5253

5354
public function isBlocked(string $key): bool
5455
{
55-
return $this->lockedKeys[$key] ?? false;
56+
return $this->lockedKeys->get(self::INNER_KEYS . $key) === true;
5657
}
5758

5859
/**
@@ -61,14 +62,18 @@ public function isBlocked(string $key): bool
6162
*/
6263
private function getLockProvider(): LockProvider
6364
{
64-
$store = $this->cache->getStore();
65-
if ($store instanceof LockProvider) {
66-
return $store;
65+
if ($this->lockProvider === null) {
66+
$store = $this->cache->getStore();
67+
if (! ($store instanceof LockProvider)) {
68+
throw new LockProviderNotFoundException(
69+
'Lockable cache not found',
70+
ExceptionInterface::LOCK_PROVIDER_NOT_FOUND
71+
);
72+
}
73+
74+
$this->lockProvider = $store;
6775
}
6876

69-
throw new LockProviderNotFoundException(
70-
'Lockable cache not found',
71-
ExceptionInterface::LOCK_PROVIDER_NOT_FOUND
72-
);
77+
return $this->lockProvider;
7378
}
7479
}

src/Internal/Service/StateService.php

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,43 @@
44

55
namespace Bavix\Wallet\Internal\Service;
66

7+
use Illuminate\Contracts\Cache\Factory as CacheFactory;
8+
use Illuminate\Contracts\Cache\Repository as CacheRepository;
9+
710
final class StateService implements StateServiceInterface
811
{
9-
/**
10-
* @var array<string, string>
11-
*/
12-
private array $forks = [];
12+
private const PREFIX_FORKS = 'wallet_forks::';
13+
14+
private const PREFIX_FORK_CALL = 'wallet_fork_call::';
1315

14-
/**
15-
* @var array<string, callable>
16-
*/
17-
private array $forkCallables = [];
16+
private CacheRepository $forks;
17+
18+
private CacheRepository $forkCallables;
19+
20+
public function __construct(CacheFactory $cacheFactory)
21+
{
22+
$this->forks = $cacheFactory->store('array');
23+
$this->forkCallables = $cacheFactory->store('array');
24+
}
1825

1926
public function fork(string $uuid, callable $value): void
2027
{
21-
$this->forkCallables[$uuid] ??= $value;
28+
$this->forkCallables->add(self::PREFIX_FORK_CALL . $uuid, $value);
2229
}
2330

2431
public function get(string $uuid): ?string
2532
{
26-
if ($this->forkCallables[$uuid] ?? null) {
27-
$callable = $this->forkCallables[$uuid];
28-
unset($this->forkCallables[$uuid]);
29-
30-
$this->forks[$uuid] = $callable();
33+
$callable = $this->forkCallables->pull(self::PREFIX_FORK_CALL . $uuid);
34+
if ($callable !== null) {
35+
$this->forks->put(self::PREFIX_FORKS . $uuid, (string) $callable());
3136
}
3237

33-
return $this->forks[$uuid] ?? null;
38+
return $this->forks->get(self::PREFIX_FORKS . $uuid);
3439
}
3540

3641
public function drop(string $uuid): void
3742
{
38-
unset($this->forks[$uuid], $this->forkCallables[$uuid]);
43+
$this->forkCallables->delete(self::PREFIX_FORK_CALL . $uuid);
44+
$this->forks->delete(self::PREFIX_FORKS . $uuid);
3945
}
4046
}

src/Internal/Service/StorageService.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
final class StorageService implements StorageServiceInterface
1212
{
13+
private const PREFIX = 'wallet_strg::';
14+
1315
public function __construct(
1416
private MathServiceInterface $mathService,
1517
private CacheRepository $cacheRepository
@@ -23,15 +25,15 @@ public function flush(): bool
2325

2426
public function missing(string $uuid): bool
2527
{
26-
return $this->cacheRepository->forget($uuid);
28+
return $this->cacheRepository->forget(self::PREFIX . $uuid);
2729
}
2830

2931
/**
3032
* @throws RecordNotFoundException
3133
*/
3234
public function get(string $uuid): string
3335
{
34-
$value = $this->cacheRepository->get($uuid);
36+
$value = $this->cacheRepository->get(self::PREFIX . $uuid);
3537
if ($value === null) {
3638
throw new RecordNotFoundException(
3739
'The repository did not find the object',
@@ -44,7 +46,7 @@ public function get(string $uuid): string
4446

4547
public function sync(string $uuid, float|int|string $value): bool
4648
{
47-
return $this->cacheRepository->set($uuid, $value);
49+
return $this->cacheRepository->forever(self::PREFIX . $uuid, $this->mathService->round($value));
4850
}
4951

5052
/**
@@ -53,7 +55,7 @@ public function sync(string $uuid, float|int|string $value): bool
5355
public function increase(string $uuid, float|int|string $value): string
5456
{
5557
$result = $this->mathService->add($this->get($uuid), $value);
56-
$this->sync($uuid, $result);
58+
$this->sync($uuid, $this->mathService->round($result));
5759

5860
return $this->mathService->round($result);
5961
}

src/Services/RegulatorService.php

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -86,29 +86,32 @@ public function decrease(Wallet $wallet, float|int|string $value): string
8686

8787
public function approve(): void
8888
{
89-
foreach ($this->wallets as $wallet) {
90-
$diffValue = $this->diff($wallet);
91-
if ($this->mathService->compare($diffValue, 0) === 0) {
92-
continue;
93-
}
94-
95-
$balance = $this->bookkeeperService->increase($wallet, $diffValue);
96-
$wallet->newQuery()
97-
->whereKey($wallet->getKey())
98-
->update([
89+
try {
90+
foreach ($this->wallets as $wallet) {
91+
$diffValue = $this->diff($wallet);
92+
if ($this->mathService->compare($diffValue, 0) === 0) {
93+
continue;
94+
}
95+
96+
$before = $this->bookkeeperService->amount($wallet);
97+
$balance = $this->bookkeeperService->increase($wallet, $diffValue);
98+
$wallet->newQuery()
99+
->whereKey($wallet->getKey())
100+
->update([
101+
'balance' => $balance,
102+
]) // ?qN
103+
;
104+
$wallet->fill([
99105
'balance' => $balance,
100-
]) // ?qN
101-
;
102-
$wallet->fill([
103-
'balance' => $balance,
104-
])->syncOriginalAttribute('balance');
105-
106-
$event = $this->balanceUpdatedEventAssembler->create($wallet);
107-
$this->dispatcherService->dispatch($event);
108-
}
106+
])->syncOriginalAttribute('balance');
109107

110-
$this->dispatcherService->flush();
111-
$this->purge();
108+
$event = $this->balanceUpdatedEventAssembler->create($wallet);
109+
$this->dispatcherService->dispatch($event);
110+
}
111+
} finally {
112+
$this->dispatcherService->flush();
113+
$this->purge();
114+
}
112115
}
113116

114117
public function purge(): void

src/WalletServiceProvider.php

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ private function shouldMigrate(): bool
203203
*/
204204
private function internal(array $configure): void
205205
{
206-
$this->app->bind(StorageServiceInterface::class, $configure['storage'] ?? StorageService::class);
206+
$this->app->alias($configure['storage'] ?? StorageService::class, 'wallet.internal.storage');
207207

208208
$this->app->singleton(ClockServiceInterface::class, $configure['clock'] ?? ClockService::class);
209209
$this->app->singleton(DatabaseServiceInterface::class, $configure['database'] ?? DatabaseService::class);
@@ -247,31 +247,39 @@ private function services(array $configure, array $cache): void
247247
$this->app->singleton(TransferServiceInterface::class, $configure['transfer'] ?? TransferService::class);
248248
$this->app->singleton(WalletServiceInterface::class, $configure['wallet'] ?? WalletService::class);
249249

250-
$this->app->singleton(BookkeeperServiceInterface::class, fn () => $this->app->make(
251-
$configure['bookkeeper'] ?? BookkeeperService::class,
252-
[
253-
'storageService' => $this->app->make(
254-
StorageServiceLockDecorator::class,
250+
// bookkeepper service
251+
$this->app->when(StorageServiceLockDecorator::class)
252+
->needs(StorageServiceInterface::class)
253+
->give(function () use ($cache) {
254+
return $this->app->make(
255+
'wallet.internal.storage',
255256
[
256-
'cacheRepository' => $this->app->make(CacheFactory::class)
257+
'cacheRepository' => $this->app->get(CacheFactory::class)
257258
->store($cache['driver'] ?? 'array'),
258259
],
259-
),
260-
]
261-
));
262-
263-
$this->app->singleton(RegulatorServiceInterface::class, fn () => $this->app->make(
264-
$configure['regulator'] ?? RegulatorService::class,
265-
[
266-
'storageService' => $this->app->make(
267-
StorageServiceInterface::class,
260+
);
261+
});
262+
263+
$this->app->when($configure['bookkeeper'] ?? BookkeeperService::class)
264+
->needs(StorageServiceInterface::class)
265+
->give(StorageServiceLockDecorator::class);
266+
267+
$this->app->singleton(BookkeeperServiceInterface::class, $configure['bookkeeper'] ?? BookkeeperService::class);
268+
269+
// regulator service
270+
$this->app->when($configure['regulator'] ?? RegulatorService::class)
271+
->needs(StorageServiceInterface::class)
272+
->give(function () {
273+
return $this->app->make(
274+
'wallet.internal.storage',
268275
[
269276
'cacheRepository' => clone $this->app->make(CacheFactory::class)
270277
->store('array'),
271278
],
272-
),
273-
]
274-
));
279+
);
280+
});
281+
282+
$this->app->singleton(RegulatorServiceInterface::class, $configure['regulator'] ?? RegulatorService::class);
275283
}
276284

277285
/**

tests/Units/Service/StorageTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use Bavix\Wallet\Internal\Decorator\StorageServiceLockDecorator;
88
use Bavix\Wallet\Internal\Exceptions\ExceptionInterface;
99
use Bavix\Wallet\Internal\Exceptions\RecordNotFoundException;
10-
use Bavix\Wallet\Internal\Service\StorageServiceInterface;
10+
use Bavix\Wallet\Internal\Service\StorageService;
1111
use Bavix\Wallet\Test\Infra\TestCase;
1212

1313
/**
@@ -19,7 +19,7 @@ public function testFlush(): void
1919
{
2020
$this->expectException(RecordNotFoundException::class);
2121
$this->expectExceptionCode(ExceptionInterface::RECORD_NOT_FOUND);
22-
$storage = app(StorageServiceInterface::class);
22+
$storage = app(StorageService::class);
2323

2424
self::assertTrue($storage->sync('hello', 34));
2525
self::assertTrue($storage->sync('world', 42));

0 commit comments

Comments
 (0)