Snapshotter::snapshotMustBeCreated()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
/**
4
 * Event Sourcing implementation.
5
 *
6
 * @author  Maksim Masiukevich <[email protected]>
7
 * @license MIT
8
 * @license https://opensource.org/licenses/MIT
9
 */
10
11
declare(strict_types = 1);
12
13
namespace ServiceBus\EventSourcing\Snapshots;
14
15
use function Amp\call;
16
use Amp\Promise;
17
use Psr\Log\LoggerInterface;
18
use Psr\Log\NullLogger;
19
use ServiceBus\EventSourcing\Aggregate;
20
use ServiceBus\EventSourcing\AggregateId;
21
use ServiceBus\EventSourcing\Snapshots\Store\SnapshotStore;
22
use ServiceBus\EventSourcing\Snapshots\Triggers\SnapshotTrigger;
23
24
/**
25
 *
26
 */
27
final class Snapshotter
28
{
29
    /** @var SnapshotStore  */
30
    private $store;
31
32
    /**
33
     * Snapshot generation trigger.
34
     *
35
     * @var SnapshotTrigger
36
     */
37
    private $trigger;
38
39
    /** @var LoggerInterface */
40
    private $logger;
41
42 14
    public function __construct(
43
        SnapshotStore $store,
44
        SnapshotTrigger $trigger,
45
        LoggerInterface $logger = null
46
    ) {
47 14
        $this->store   = $store;
48 14
        $this->trigger = $trigger;
49 14
        $this->logger  = $logger ?? new NullLogger();
50 14
    }
51
52
    /**
53
     * Load snapshot for aggregate.
54
     *
55
     * Returns \ServiceBus\EventSourcing\Snapshots\Snapshot|null
56
     */
57 7
    public function load(AggregateId $id): Promise
58
    {
59 7
        return call(
60
            function() use ($id): \Generator
61
            {
62 7
                $snapshot = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $snapshot is dead and can be removed.
Loading history...
63
64
                try
65
                {
66
                    /** @var Snapshot|null $snapshot */
67 7
                    $snapshot = yield $this->store->load($id);
68
                }
69
                catch (\Throwable $throwable)
70
                {
71
                    $this->logger->error(
72
                        'Error loading snapshot of aggregate with identifier "{aggregateIdClass}:{aggregateId}"',
73
                        [
74
                            'aggregateIdClass' => \get_class($id),
75
                            'aggregateId'      => $id->toString(),
76
                            'throwableMessage' => $throwable->getMessage(),
77
                            'throwablePoint'   => \sprintf('%s:%d', $throwable->getFile(), $throwable->getLine()),
78
                        ]
79
                    );
80
                }
81
82 7
                return $snapshot;
83 7
            }
84
        );
85
    }
86
87
    /**
88
     * Store new snapshot.
89
     */
90 7
    public function store(Snapshot $snapshot): Promise
91
    {
92 7
        return call(
93
            function() use ($snapshot): \Generator
94
            {
95 7
                $id = $snapshot->aggregate->id();
96
97
                try
98
                {
99 7
                    yield $this->store->remove($id);
100 7
                    yield $this->store->save($snapshot);
101
                }
102
                catch (\Throwable $throwable)
103
                {
104
                    $this->logger->error(
105
                        'Error saving snapshot of aggregate with identifier "{aggregateIdClass}:{aggregateId}"',
106
                        [
107
                            'aggregateIdClass' => \get_class($id),
108
                            'aggregateId'      => $id->toString(),
109
                            'throwableMessage' => $throwable->getMessage(),
110
                            'throwablePoint'   => \sprintf('%s:%d', $throwable->getFile(), $throwable->getLine()),
111
                        ]
112
                    );
113
                }
114
                finally
115 7
                {
116 7
                    unset($id);
117
                }
118 7
            }
119
        );
120
    }
121
122
    /**
123
     * A snapshot must be created.
124
     */
125 7
    public function snapshotMustBeCreated(Aggregate $aggregate, Snapshot $previousSnapshot = null): bool
126
    {
127 7
        return $this->trigger->snapshotMustBeCreated($aggregate, $previousSnapshot);
128
    }
129
}
130