def test(self): with ExampleApplicationWithAlternativeSequencedItemType(self.datastore.session) as app: # Create entity. entity1 = create_new_example(a='a', b='b') self.assertIsInstance(entity1.id, UUID) self.assertEqual(entity1.a, 'a') self.assertEqual(entity1.b, 'b') # Check there is a stored event. all_records = list(app.event_store.active_record_strategy.all_records()) assert len(all_records) == 1 stored_event, _ = all_records[0] assert stored_event.originator_id == entity1.id assert stored_event.originator_version == 0 # Read entity from repo. retrieved_obj = app.repository[entity1.id] self.assertEqual(retrieved_obj.id, entity1.id)
def test(self): with ExampleApplicationWithAlternativeSequencedItemType() as app: # Create entity. entity1 = create_new_example(a='a', b='b') self.assertIsInstance(entity1.id, UUID) self.assertEqual(entity1.a, 'a') self.assertEqual(entity1.b, 'b') # Check there is a stored event. all_records = list(app.event_store.record_manager.all_records()) assert len(all_records) == 1, len(all_records) stored_event = all_records[0] assert isinstance(stored_event, StoredEventRecord), stored_event assert stored_event.originator_id == entity1.id assert stored_event.originator_version == 0 # Read entity from repo. retrieved_obj = app.repository[entity1.id] self.assertEqual(retrieved_obj.id, entity1.id)
def _test(self): with ExampleApplicationWithAlternativeSequencedItemType( self.datastore.session) as app: # Create entity. entity1 = create_new_example(a='a', b='b') self.assertIsInstance(entity1.id, UUID) self.assertEqual(entity1.a, 'a') self.assertEqual(entity1.b, 'b') # Check there is a stored event. all_records = list( app.event_store.record_manager.get_notifications()) self.assertEqual(1, len(all_records)) stored_event = all_records[0] self.assertEqual(stored_event.originator_id, entity1.id) self.assertEqual(stored_event.originator_version, 0) # Read entity from repo. retrieved_obj = app.repository[entity1.id] self.assertEqual(retrieved_obj.id, entity1.id)
def test(self): with ExampleApplicationWithExtendedSequencedItemType( self.datastore.session) as app: # Create entity. entity1 = create_new_example(a='a', b='b') self.assertIsInstance(entity1.id, UUID) self.assertEqual(entity1.a, 'a') self.assertEqual(entity1.b, 'b') # Check there is a stored event. all_records = list(app.event_store.record_manager.all_records()) self.assertEqual(len(all_records), 1) record = all_records[0] self.assertEqual(record.sequence_id, entity1.id) self.assertEqual(record.position, 0) self.assertEqual(record.event_type, 'Example.Created', record.event_type) self.assertEqual(record.timestamp, entity1.__created_on__) # Read entity from repo. retrieved_obj = app.repository[entity1.id] self.assertEqual(retrieved_obj.id, entity1.id)
def test_entity_performance(self): """ Reports on the performance of Example entity and repo. NB: This test doesn't actually assert anything, so it isn't really a test. """ with self.construct_application() as app: # Initialise dict of entities. self.entities = {} report_name = type(self).__name__[4:] print("\n\n{} report:\n".format(report_name)) repetitions = 10 # 10 # NB: Use range(1, 5) to test whether we can get more than 10000 items # from Cassandra. # Setup a number of entities, with different lengths of event history. for i in range(0, 4): # Initialise table with other entities. num_other_entities = i filling = [] for _ in range(num_other_entities): filling.append(create_new_example(a=1, b=2)) # b = str([uuid4().hex for _ in range(100000)]) b = 2 example = create_new_example(a=1, b=b) self.entities[i] = example # Beat a number of times. num_beats = int(floor(10**i)) start_beating = time.time() for _ in range(num_beats): # print("Beat example") example.beat_heart() for other in filling: other.beat_heart() total_beats = num_beats * (1 + len(filling)) time_beating = time.time() - start_beating try: beats_per_second = total_beats / time_beating except ZeroDivisionError as e: print("Warning: beats per second {} / {}: {}".format( total_beats, time_beating, e)) beats_per_second = -999999999999.99999999 try: beat_period = time_beating / total_beats except ZeroDivisionError as e: print("Warning: beat period {} / {}: {}".format( time_beating, total_beats, e)) beat_period = -999999999999.9999999 print( "Time to beat {} times: {:.4f}s ({:.0f} beats/s, {:.6f}s each)" "".format( num_beats, time_beating / (1 + num_other_entities), beats_per_second, beat_period, )) # Get the last n events from the repo. def last_n(n): n = min(n, num_beats + 1) assert isinstance(app.example_repository.event_store, EventStore) start_last_n = time.time() events = app.example_repository.event_store.list_events( originator_id=example.id, gt=num_beats - n, ) assert len(events) == n, "Asked for %s but got %s" % ( n, len(events), ) time_last_n = (time.time() - start_last_n) / repetitions # num_retrieved_events = len(last_n_stored_events) events_per_second = n / time_last_n print( ("Time to get last {:>" + str(i + 1) + "} events after {} events: {:.6f}s ({:.0f} events/s)" "").format(n, num_beats + 1, time_last_n, events_per_second)) for j in range(0, i + 1): last_n(10**j) # Get the entity by replaying all events (which it must since there # isn't a snapshot). start_replay = time.time() for _ in range(repetitions): example = app.example_repository[example.id] assert isinstance(example, Example) heartbeats = example.count_heartbeats() assert heartbeats == num_beats, (heartbeats, num_beats) time_replaying = (time.time() - start_replay) / repetitions print( "Time to replay {} beats: {:.2f}s ({:.0f} beats/s, {:.6f}s each)" "".format( num_beats, time_replaying, num_beats / time_replaying, time_replaying / num_beats, )) # Take snapshot, and beat heart a few more times. app.example_repository.take_snapshot(example.id) extra_beats = 4 for _ in range(extra_beats): example.beat_heart() num_beats += extra_beats # Get the entity using snapshot and replaying events since the snapshot. start_replay = time.time() for _ in range(repetitions): example = app.example_repository[example.id] time_replaying = (time.time() - start_replay) / repetitions events_per_second = ( extra_beats + 1) / time_replaying # +1 for the snapshot event beats_per_second = num_beats / time_replaying print( "Time to replay snapshot with {} extra beats: {:.6f}s ({:.0f} " "events/s, {:.0f} beats/s)" "".format(extra_beats, time_replaying, events_per_second, beats_per_second)) print("")
def test_entity_lifecycle(self): # Check the factory creates an instance. example1 = create_new_example(a=1, b=2) self.assertIsInstance(example1, Example) # Check the instance is equal to itself. self.assertEqual(example1, example1) # Check the instance is equal to a clone of itself. clone = object.__new__(type(example1)) clone.__dict__.update(example1.__dict__) self.assertEqual(example1, clone) # Check the properties of the Example class. self.assertEqual(1, example1.a) self.assertEqual(2, example1.b) # Check the properties of the TimestampedVersionedEntity class. self.assertTrue(example1.id) self.assertEqual(1, example1.version) self.assertTrue(example1.created_on) self.assertTrue(example1.last_modified_on) self.assertEqual(example1.created_on, example1.last_modified_on) # Check a different type with the same values is not "equal" to the first. class Subclass(Example): pass other = object.__new__(Subclass) other.__dict__.update(example1.__dict__) self.assertEqual(example1.__dict__, other.__dict__) self.assertNotEqual(example1, other) # Check a second instance with the same values is not "equal" to the first. example2 = create_new_example(a=1, b=2) self.assertEqual(type(example1), type(example2)) self.assertNotEqual(example1, example2) # Setup the repo. repo = ExampleRepository(self.entity_event_store) # Check the example entities can be retrieved from the example repository. entity1 = repo[example1.id] self.assertIsInstance(entity1, Example) self.assertEqual(1, entity1.a) self.assertEqual(2, entity1.b) entity2 = repo[example2.id] self.assertIsInstance(entity2, Example) self.assertEqual(1, entity2.a) self.assertEqual(2, entity2.b) # Check the entity can be updated. entity1.a = 100 self.assertEqual(100, repo[entity1.id].a) entity1.b = -200 self.assertEqual(-200, repo[entity1.id].b) self.assertEqual(repo[entity1.id].created_on, entity1.created_on) self.assertEqual(repo[entity1.id].last_modified_on, entity1.last_modified_on) self.assertNotEqual(entity1.last_modified_on, entity1.created_on) self.assertEqual(0, entity1.count_heartbeats()) entity1.beat_heart() entity1.beat_heart() entity1.beat_heart() self.assertEqual(3, entity1.count_heartbeats()) self.assertEqual(3, repo[entity1.id].count_heartbeats()) # Check the entity can publish multiple events simultaneously. entity1.beat_heart(number_of_beats=3) self.assertEqual(6, repo[entity1.id].count_heartbeats()) # Check the entity can be discarded. entity1.discard() # Check the repo now raises a KeyError. self.assertRaises(RepositoryKeyError, repo.__getitem__, entity1.id) # Check the entity can't be discarded twice. self.assertRaises(AssertionError, entity1.discard) # Should fail to validate event with wrong entity ID. with self.assertRaises(MismatchedOriginatorIDError): entity2._validate_originator( VersionedEntity.Event( originator_id=uuid4(), originator_version=0 ) ) # Should fail to validate event with wrong entity version. with self.assertRaises(MismatchedOriginatorVersionError): entity2._validate_originator( VersionedEntity.Event( originator_id=entity2.id, originator_version=0, ) ) # Should validate event with correct entity ID and version. entity2._validate_originator( VersionedEntity.Event( originator_id=entity2.id, originator_version=entity2.version, ) ) # Check an entity cannot be reregistered with the ID of a discarded entity. replacement_event = Example.Created(originator_id=entity1.id, a=11, b=12) with self.assertRaises(ConcurrencyError): publish(event=replacement_event)
def test_take_snapshot(self): self.entity_persistence_policy = PersistencePolicy( event_store=self.entity_event_store, event_type=VersionedEntity.Event, ) self.snapshot_persistence_policy = PersistencePolicy( event_store=self.snapshot_store, event_type=Snapshot, ) snapshot_strategy = EventSourcedSnapshotStrategy( event_store=self.snapshot_store ) event_player = EventPlayer( event_store=self.entity_event_store, mutator=Example._mutate, snapshot_strategy=snapshot_strategy ) # Take a snapshot with a non-existent ID. unregistered_id = uuid4() # Check no snapshot is taken. self.assertIsNone(event_player.take_snapshot(unregistered_id)) # Check no snapshot is available. self.assertIsNone(event_player.get_snapshot(unregistered_id)) # Create a new entity. registered_example = create_new_example(a=123, b=234) # Take a snapshot of the new entity (no previous snapshots). snapshot1 = event_player.take_snapshot(registered_example.id, lt=registered_example.version) # Check the snapshot is pegged to the last applied version. self.assertEqual(snapshot1.originator_version, 0) # Replay from this snapshot. entity_from_snapshot1 = entity_from_snapshot(snapshot1) retrieved_example = event_player.replay_entity(registered_example.id, initial_state=entity_from_snapshot1, gte=entity_from_snapshot1._version) # Check the attributes are correct. self.assertEqual(retrieved_example.a, 123) # Remember the version now. version1 = retrieved_example._version self.assertEqual(version1, 1) # Change attribute value. retrieved_example.a = 999 # Remember the version now. version2 = retrieved_example._version self.assertEqual(version2, 2) # Change attribute value. retrieved_example.a = 9999 # Remember the version now. version3 = retrieved_example._version self.assertEqual(version3, 3) # Check the event sourced entities are correct. retrieved_example = event_player.replay_entity(registered_example.id) self.assertEqual(retrieved_example.a, 9999) # Take another snapshot. snapshot2 = event_player.take_snapshot(retrieved_example.id, lt=retrieved_example.version) # Replay from this snapshot. initial_state = entity_from_snapshot(snapshot2) retrieved_example = event_player.replay_entity( registered_example.id, initial_state=initial_state, gte=initial_state._version, ) # Check the attributes are correct. self.assertEqual(retrieved_example.a, 9999) # Check we can get historical state at version1. retrieved_example = event_player.replay_entity(registered_example.id, lt=version1) self.assertEqual(retrieved_example.a, 123) # Check we can get historical state at version2. retrieved_example = event_player.replay_entity(registered_example.id, lt=version2) self.assertEqual(retrieved_example.a, 999) # Check we can get historical state at version3. retrieved_example = event_player.replay_entity(registered_example.id, lt=version3) self.assertEqual(retrieved_example.a, 9999) # Similarly, check we can get historical state using a snapshot initial_state = entity_from_snapshot(snapshot1) retrieved_example = event_player.replay_entity( registered_example.id, initial_state=initial_state, gte=initial_state._version, lt=version2, ) self.assertEqual(retrieved_example.a, 999) # Discard the entity. registered_example = event_player.replay_entity(registered_example.id) registered_example.discard() # Take snapshot of discarded entity. snapshot3 = event_player.take_snapshot(registered_example.id) self.assertIsNone(snapshot3.state) self.assertIsNone(entity_from_snapshot(snapshot3))
def test_entity_lifecycle(self): # Check the factory creates an instance. example1 = Example.__create__(a=1, b=2) self.assertIsInstance(example1, Example) # Check the instance is equal to itself. self.assertEqual(example1, example1) # Check the instance is equal to a clone of itself. clone = object.__new__(type(example1)) clone.__dict__.update(example1.__dict__) self.assertEqual(example1, clone) # Check the properties of the Example class. self.assertEqual(1, example1.a) self.assertEqual(2, example1.b) # Check the properties of the TimestampedVersionedEntity class. self.assertTrue(example1.id) self.assertEqual(example1.__version__, 0) self.assertTrue(example1.__created_on__) self.assertLess(example1.__created_on__, time.time()) self.assertGreater(example1.__created_on__, time.time() - 1) self.assertTrue(example1.__last_modified__) self.assertEqual(example1.__created_on__, example1.__last_modified__) # Test the datetime_from_timestamp() converts ok. tt = time.time() dt = datetime.datetime.utcnow() self.assertEqual(datetime_from_timestamp(tt).hour, dt.hour) # Check can get datetime from timestamps, and it corresponds to UTC. dt = datetime_from_timestamp(example1.__created_on__) self.assertLess(dt, datetime.datetime.utcnow()) self.assertGreater(dt, datetime.datetime.utcnow() - datetime.timedelta(1)) # Check a different type with the same values is not "equal" to the first. class Subclass(Example): pass other = object.__new__(Subclass) other.__dict__.update(example1.__dict__) self.assertEqual(example1.__dict__, other.__dict__) self.assertNotEqual(example1, other) # Check a second instance with the same values is not "equal" to the first. example2 = create_new_example(a=1, b=2) self.assertEqual(type(example1), type(example2)) self.assertNotEqual(example1, example2) # Check entity not hashable. with self.assertRaises(TypeError): hash(example1) # Setup the repo. repo = ExampleRepository(self.entity_event_store) # Check the example entities can be retrieved from the example repository. entity1 = repo[example1.id] self.assertIsInstance(entity1, Example) self.assertEqual(1, entity1.a) self.assertEqual(2, entity1.b) entity2 = repo[example2.id] self.assertIsInstance(entity2, Example) self.assertEqual(1, entity2.a) self.assertEqual(2, entity2.b) # Check the entity can be updated. entity1.a = 100 self.assertEqual(100, repo[entity1.id].a) entity1.b = -200 self.assertEqual(-200, repo[entity1.id].b) self.assertEqual(repo[entity1.id].__created_on__, entity1.__created_on__) self.assertEqual(repo[entity1.id].__last_modified__, entity1.__last_modified__) self.assertNotEqual(entity1.__last_modified__, entity1.__created_on__) self.assertEqual(0, entity1.count_heartbeats()) entity1.beat_heart() entity1.beat_heart() entity1.beat_heart() self.assertEqual(3, entity1.count_heartbeats()) self.assertEqual(3, repo[entity1.id].count_heartbeats()) # Check the entity can publish multiple events simultaneously. entity1.beat_heart(number_of_beats=3) self.assertEqual(6, repo[entity1.id].count_heartbeats()) # Check the entity can be discarded. entity1.__discard__() # Check the repo now raises a KeyError. self.assertRaises(RepositoryKeyError, repo.__getitem__, entity1.id) # Check the entity can't be discarded twice. self.assertRaises(AssertionError, entity1.__discard__) # Should fail to validate event with wrong entity ID. with self.assertRaises(OriginatorIDError): VersionedEntity.Event( originator_id=uuid4(), originator_version=0, ).__check_obj__(entity2) # Should fail to validate event with wrong entity version. with self.assertRaises(OriginatorVersionError): VersionedEntity.Event( originator_id=entity2.id, originator_version=0, __previous_hash__=entity2.__head__, ).__check_obj__(entity2) # Should validate event with correct entity ID and version. VersionedEntity.Event( originator_id=entity2.id, originator_version=entity2.__version__ + 1, __previous_hash__=entity2.__head__, ).__check_obj__(entity2) # Check an entity cannot be reregistered with the ID of a discarded entity. replacement_event = Example.Created( originator_id=entity1.id, a=11, b=12, originator_topic=get_topic(Example), ) with self.assertRaises(ConcurrencyError): publish(event=replacement_event)
def test_entity_lifecycle(self): # Check the factory creates an instance. example1 = create_new_example(a=1, b=2) self.assertIsInstance(example1, Example) # Check the instance is equal to itself. self.assertEqual(example1, example1) # Check the instance is equal to a clone of itself. clone = object.__new__(type(example1)) clone.__dict__.update(example1.__dict__) self.assertEqual(example1, clone) # Check the properties of the Example class. self.assertEqual(1, example1.a) self.assertEqual(2, example1.b) # Check the properties of the TimestampedVersionedEntity class. self.assertTrue(example1.id) self.assertEqual(1, example1.version) self.assertTrue(example1.created_on) self.assertTrue(example1.last_modified) self.assertEqual(example1.created_on, example1.last_modified) # Check a different type with the same values is not "equal" to the first. class Subclass(Example): pass other = object.__new__(Subclass) other.__dict__.update(example1.__dict__) self.assertEqual(example1.__dict__, other.__dict__) self.assertNotEqual(example1, other) # Check a second instance with the same values is not "equal" to the first. example2 = create_new_example(a=1, b=2) self.assertEqual(type(example1), type(example2)) self.assertNotEqual(example1, example2) # Setup the repo. repo = ExampleRepository(self.entity_event_store) # Check the example entities can be retrieved from the example repository. entity1 = repo[example1.id] self.assertIsInstance(entity1, Example) self.assertEqual(1, entity1.a) self.assertEqual(2, entity1.b) entity2 = repo[example2.id] self.assertIsInstance(entity2, Example) self.assertEqual(1, entity2.a) self.assertEqual(2, entity2.b) # Check the entity can be updated. entity1.a = 100 self.assertEqual(100, repo[entity1.id].a) entity1.b = -200 self.assertEqual(-200, repo[entity1.id].b) self.assertEqual(repo[entity1.id].created_on, entity1.created_on) self.assertEqual(repo[entity1.id].last_modified, entity1.last_modified) self.assertNotEqual(entity1.last_modified, entity1.created_on) self.assertEqual(0, entity1.count_heartbeats()) entity1.beat_heart() entity1.beat_heart() entity1.beat_heart() self.assertEqual(3, entity1.count_heartbeats()) self.assertEqual(3, repo[entity1.id].count_heartbeats()) # Check the entity can publish multiple events simultaneously. entity1.beat_heart(number_of_beats=3) self.assertEqual(6, repo[entity1.id].count_heartbeats()) # Check the entity can be discarded. entity1.discard() # Check the repo now raises a KeyError. self.assertRaises(RepositoryKeyError, repo.__getitem__, entity1.id) # Check the entity can't be discarded twice. self.assertRaises(AssertionError, entity1.discard) # Should fail to validate event with wrong entity ID. with self.assertRaises(MismatchedOriginatorIDError): entity2._validate_originator( VersionedEntity.Event(originator_id=uuid4(), originator_version=0)) # Should fail to validate event with wrong entity version. with self.assertRaises(MismatchedOriginatorVersionError): entity2._validate_originator( VersionedEntity.Event( originator_id=entity2.id, originator_version=0, )) # Should validate event with correct entity ID and version. entity2._validate_originator( VersionedEntity.Event( originator_id=entity2.id, originator_version=entity2.version, )) # Check an entity cannot be reregistered with the ID of a discarded entity. replacement_event = Example.Created(originator_id=entity1.id, a=11, b=12) with self.assertRaises(ConcurrencyError): publish(event=replacement_event)
def test_take_snapshot(self): self.entity_persistence_policy = PersistencePolicy( event_store=self.entity_event_store, event_type=VersionedEntity.Event, ) self.snapshot_persistence_policy = PersistencePolicy( event_store=self.snapshot_store, event_type=Snapshot, ) snapshot_strategy = EventSourcedSnapshotStrategy( event_store=self.snapshot_store) event_player = EventPlayer(event_store=self.entity_event_store, mutator=Example._mutate, snapshot_strategy=snapshot_strategy) # Take a snapshot with a non-existent ID. unregistered_id = uuid4() # Check no snapshot is taken. self.assertIsNone(event_player.take_snapshot(unregistered_id)) # Check no snapshot is available. self.assertIsNone(event_player.get_snapshot(unregistered_id)) # Create a new entity. registered_example = create_new_example(a=123, b=234) # Take a snapshot of the new entity (no previous snapshots). snapshot1 = event_player.take_snapshot(registered_example.id, lt=registered_example.version) # Check the snapshot is pegged to the last applied version. self.assertEqual(snapshot1.originator_version, 0) # Replay from this snapshot. entity_from_snapshot1 = entity_from_snapshot(snapshot1) retrieved_example = event_player.replay_entity( registered_example.id, initial_state=entity_from_snapshot1, gte=entity_from_snapshot1._version) # Check the attributes are correct. self.assertEqual(retrieved_example.a, 123) # Remember the version now. version1 = retrieved_example._version self.assertEqual(version1, 1) # Change attribute value. retrieved_example.a = 999 # Remember the version now. version2 = retrieved_example._version self.assertEqual(version2, 2) # Change attribute value. retrieved_example.a = 9999 # Remember the version now. version3 = retrieved_example._version self.assertEqual(version3, 3) # Check the event sourced entities are correct. retrieved_example = event_player.replay_entity(registered_example.id) self.assertEqual(retrieved_example.a, 9999) # Take another snapshot. snapshot2 = event_player.take_snapshot(retrieved_example.id, lt=retrieved_example.version) # Replay from this snapshot. initial_state = entity_from_snapshot(snapshot2) retrieved_example = event_player.replay_entity( registered_example.id, initial_state=initial_state, gte=initial_state._version, ) # Check the attributes are correct. self.assertEqual(retrieved_example.a, 9999) # Check we can get historical state at version1. retrieved_example = event_player.replay_entity(registered_example.id, lt=version1) self.assertEqual(retrieved_example.a, 123) # Check we can get historical state at version2. retrieved_example = event_player.replay_entity(registered_example.id, lt=version2) self.assertEqual(retrieved_example.a, 999) # Check we can get historical state at version3. retrieved_example = event_player.replay_entity(registered_example.id, lt=version3) self.assertEqual(retrieved_example.a, 9999) # Similarly, check we can get historical state using a snapshot initial_state = entity_from_snapshot(snapshot1) retrieved_example = event_player.replay_entity( registered_example.id, initial_state=initial_state, gte=initial_state._version, lt=version2, ) self.assertEqual(retrieved_example.a, 999) # Discard the entity. registered_example = event_player.replay_entity(registered_example.id) registered_example.discard() # Take snapshot of discarded entity. snapshot3 = event_player.take_snapshot(registered_example.id) self.assertIsNone(snapshot3.state) self.assertIsNone(entity_from_snapshot(snapshot3))
def create_new_example(self, foo="", a="", b=""): """Entity object factory.""" return create_new_example(foo=foo, a=a, b=b)
def create_new_example(self, foo='', a='', b=''): """Entity object factory.""" return create_new_example(foo=foo, a=a, b=b)
def test_entity_performance(self): """ Reports on the performance of Example entity and repo. NB: This test doesn't actually assert anything, so it isn't really a test. """ with self.construct_application() as app: # Initialise dict of entities. self.entities = {} report_name = type(self).__name__[4:] print("\n\n{} report:\n".format(report_name)) repetitions = 10 # 10 # NB: Use range(1, 5) to test whether we can get more than 10000 items from Cassandra. # Setup a number of entities, with different lengths of event history. for i in six.moves.range(0, 4): # Initialise table with other entities. num_other_entities = i filling = [] for _ in six.moves.range(num_other_entities): filling.append(create_new_example(a=1, b=2)) # b = str([uuid4().hex for _ in six.moves.range(100000)]) b = 2 example = create_new_example(a=1, b=b) self.entities[i] = example # Beat a number of times. num_beats = int(floor(10 ** i)) start_beating = time.time() for _ in six.moves.range(num_beats): # print("Beat example") example.beat_heart() for other in filling: other.beat_heart() total_beats = num_beats * (1 + len(filling)) time_beating = time.time() - start_beating try: beats_per_second = total_beats / time_beating except ZeroDivisionError as e: print("Warning: beats per second {} / {}: {}".format(total_beats, time_beating, e)) beats_per_second = -999999999999.99999999 try: beat_period = time_beating / total_beats except ZeroDivisionError as e: print("Warning: beat period {} / {}: {}".format(time_beating, total_beats, e)) beat_period = -999999999999.9999999 print("Time to beat {} times: {:.4f}s ({:.0f} beats/s, {:.6f}s each)" "".format(num_beats, time_beating / (1 + num_other_entities), beats_per_second, beat_period)) # Get the last n events from the repo. def last_n(n): n = min(n, num_beats + 1) assert isinstance(app.example_repository.event_player.event_store, EventStore) ars = app.example_repository.event_player.event_store.active_record_strategy assert isinstance(ars, AbstractActiveRecordStrategy) start_last_n = time.time() last_n_stored_events = [] for _ in six.moves.range(repetitions): iterator = SequencedItemIterator( active_record_strategy=ars, sequence_id=example.id, limit=n, is_ascending=False, ) last_n_stored_events = list(iterator) time_last_n = (time.time() - start_last_n) / repetitions num_retrieved_events = len(last_n_stored_events) events_per_second = num_retrieved_events / time_last_n print(("Time to get last {:>" + str(i + 1) + "} events after {} events: {:.6f}s ({:.0f} events/s)" "").format(n, num_beats + 1, time_last_n, events_per_second)) for j in range(0, i + 1): last_n(10 ** j) # Get the entity by replaying all events (which it must since there isn't a snapshot). start_replay = time.time() for _ in six.moves.range(repetitions): example = app.example_repository[example.id] assert isinstance(example, Example) heartbeats = example.count_heartbeats() assert heartbeats == num_beats, (heartbeats, num_beats) time_replaying = (time.time() - start_replay) / repetitions print("Time to replay {} beats: {:.2f}s ({:.0f} beats/s, {:.6f}s each)" "".format(num_beats, time_replaying, num_beats / time_replaying, time_replaying / num_beats)) # Take snapshot, and beat heart a few more times. app.example_repository.take_snapshot(example.id, lt=example.version) extra_beats = 4 for _ in six.moves.range(extra_beats): example.beat_heart() num_beats += extra_beats # Get the entity using snapshot and replaying events since the snapshot. start_replay = time.time() for _ in six.moves.range(repetitions): example = app.example_repository[example.id] time_replaying = (time.time() - start_replay) / repetitions events_per_second = (extra_beats + 1) / time_replaying # +1 for the snapshot event beats_per_second = num_beats / time_replaying print("Time to replay snapshot with {} extra beats: {:.6f}s ({:.0f} events/s, {:.0f} beats/s)" "".format(extra_beats, time_replaying, events_per_second, beats_per_second)) print("")