Skip to content

Commit

Permalink
Merge pull request #308 from tomcizek/feature/non-transactional-in-me…
Browse files Browse the repository at this point in the history
…mory-event-store

Introducing NonTransactionalInMemoryEventStore
  • Loading branch information
prolic committed Oct 29, 2017
2 parents d41aa2d + 4371861 commit c7938e9
Show file tree
Hide file tree
Showing 5 changed files with 612 additions and 12 deletions.
4 changes: 4 additions & 0 deletions docs/interop_factories.md
Expand Up @@ -60,6 +60,10 @@ If the requirements are met, you just need to add a new section in your applicat

$eventStore = $container->get('inmemoryeventstore');

By default, `InMemoryEventStore` which is transactional, is created by factory. If you want to change this behaviour to
create `NonTransactionalInMemoryEventStore`, simply override default config of given event store to
`'transactional' => false`

#### ReadOnlyEventStoreWrapper

If you want to have a read only event store, just add `'read_only' => true` to your event store config.
Expand Down
74 changes: 63 additions & 11 deletions src/Container/InMemoryEventStoreFactory.php
Expand Up @@ -16,17 +16,22 @@
use Interop\Config\ProvidesDefaultOptions;
use Interop\Config\RequiresConfig;
use Interop\Config\RequiresConfigId;
use Prooph\Common\Event\ActionEventEmitter;
use Prooph\Common\Event\ProophActionEventEmitter;
use Prooph\EventStore\ActionEventEmitterEventStore;
use Prooph\EventStore\EventStore;
use Prooph\EventStore\Exception\ConfigurationException;
use Prooph\EventStore\Exception\InvalidArgumentException;
use Prooph\EventStore\InMemoryEventStore;
use Prooph\EventStore\Metadata\MetadataEnricher;
use Prooph\EventStore\Metadata\MetadataEnricherAggregate;
use Prooph\EventStore\Metadata\MetadataEnricherPlugin;
use Prooph\EventStore\NonTransactionalInMemoryEventStore;
use Prooph\EventStore\Plugin\Plugin;
use Prooph\EventStore\ReadOnlyEventStore;
use Prooph\EventStore\ReadOnlyEventStoreWrapper;
use Prooph\EventStore\TransactionalActionEventEmitterEventStore;
use Prooph\EventStore\TransactionalEventStore;
use Psr\Container\ContainerInterface;

final class InMemoryEventStoreFactory implements
Expand All @@ -41,6 +46,11 @@ final class InMemoryEventStoreFactory implements
*/
private $configId;

/**
* @var bool
*/
private $isTransactional;

/**
* Creates a new instance from a specified config, specifically meant to be used as static factory.
*
Expand Down Expand Up @@ -80,7 +90,9 @@ public function __invoke(ContainerInterface $container): ReadOnlyEventStore
$config = $container->get('config');
$config = $this->options($config, $this->configId);

$eventStore = new InMemoryEventStore();
$this->isTransactional = $this->isTransactional($config);

$eventStore = $this->createEventStore();

if ($config['read_only']) {
$eventStore = new ReadOnlyEventStoreWrapper($eventStore);
Expand All @@ -91,21 +103,23 @@ public function __invoke(ContainerInterface $container): ReadOnlyEventStore
}

if (! isset($config['event_emitter'])) {
$eventEmitter = new ProophActionEventEmitter(TransactionalActionEventEmitterEventStore::ALL_EVENTS);
$eventEmitter = new ProophActionEventEmitter($this->determineEventsForDefaultEmitter());
} else {
$eventEmitter = $container->get($config['event_emitter']);
}

$wrapper = new TransactionalActionEventEmitterEventStore($eventStore, $eventEmitter);
$wrapper = $this->createActionEventEmitterDecorator($eventStore, $eventEmitter);

foreach ($config['plugins'] as $pluginAlias) {
$plugin = $container->get($pluginAlias);

if (! $plugin instanceof Plugin) {
throw ConfigurationException::configurationError(sprintf(
'Plugin %s does not implement the Plugin interface',
$pluginAlias
));
throw ConfigurationException::configurationError(
sprintf(
'Plugin %s does not implement the Plugin interface',
$pluginAlias
)
);
}

$plugin->attachToEventStore($wrapper);
Expand All @@ -118,10 +132,12 @@ public function __invoke(ContainerInterface $container): ReadOnlyEventStore
$metadataEnricher = $container->get($metadataEnricherAlias);

if (! $metadataEnricher instanceof MetadataEnricher) {
throw ConfigurationException::configurationError(sprintf(
'Metadata enricher %s does not implement the MetadataEnricher interface',
$metadataEnricherAlias
));
throw ConfigurationException::configurationError(
sprintf(
'Metadata enricher %s does not implement the MetadataEnricher interface',
$metadataEnricherAlias
)
);
}

$metadataEnrichers[] = $metadataEnricher;
Expand Down Expand Up @@ -154,7 +170,43 @@ public function defaultOptions(): iterable
'metadata_enrichers' => [],
'plugins' => [],
'wrap_action_event_emitter' => true,
'transactional' => true,
'read_only' => false,
];
}

private function determineEventsForDefaultEmitter(): array
{
if ($this->isTransactional) {
return TransactionalActionEventEmitterEventStore::ALL_EVENTS;
}

return ActionEventEmitterEventStore::ALL_EVENTS;
}

private function createEventStore(): EventStore
{
if ($this->isTransactional) {
return new InMemoryEventStore();
}

return new NonTransactionalInMemoryEventStore();
}

private function createActionEventEmitterDecorator(
EventStore $eventStore,
ActionEventEmitter $actionEventEmitter
): ActionEventEmitterEventStore {
if ($this->isTransactional) {
/** @var TransactionalEventStore $eventStore */
return new TransactionalActionEventEmitterEventStore($eventStore, $actionEventEmitter);
}

return new ActionEventEmitterEventStore($eventStore, $actionEventEmitter);
}

private function isTransactional(array $config): bool
{
return isset($config['transactional']) && $config['transactional'] === true;
}
}

0 comments on commit c7938e9

Please sign in to comment.