Skip to content
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

LRU cache for the entity manager #4

Merged
merged 4 commits into from
Aug 14, 2023
Merged

LRU cache for the entity manager #4

merged 4 commits into from
Aug 14, 2023

Conversation

huntc
Copy link
Collaborator

@huntc huntc commented Aug 10, 2023

The entity manager now uses a simple and evolved LRU cache given that we're in control of the concurrency aspects (as opposed to using a cache supporting concurrency).

I also upped the working set (capacity) to 10. We of course still permit the developer to override that, and I've not forgotten about the potential for a config struct as we move forward.

@huntc huntc added the enhancement New feature or request label Aug 10, 2023
@huntc huntc requested a review from patriknw August 10, 2023 06:59
@huntc huntc self-assigned this Aug 10, 2023
@@ -183,7 +183,7 @@ where
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adapter.produce may return many records, right? That means that after above while ... update_entity it's not guaranteed that the entities cache contains the entity_id. Shouldn't produce be changed so that only loads the requested entity_id, nothing more?

Also, if I'm not reading things completely wrong the current implementation of FileLogTopicAdapter.produce just returns an empty stream.

Adding some test that validates that the state is recovered also after cache eviction might be good.

Copy link
Collaborator Author

@huntc huntc Aug 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adapter.produce may return many records, right?

Not anymore. I changed that contract when the initial produce was introduced in the first PR. It is now allowed only to produce those for the entity id.

Copy link
Collaborator Author

@huntc huntc Aug 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, if I'm not reading things completely wrong the current implementation of FileLogTopicAdapter.produce just returns an empty stream.

Ah yeah, I now need to fix that given the LRU cache.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding some test that validates that the state is recovered also after cache eviction might be good.

I will do so.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've provided 3 more commits starting at d4edc4d. There's pretty good test coverage now, and a few optimisations.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...and produce now produces events per entity id.

The entity manager now uses a simple and evolved LRU cache given that we're in control of the concurrency aspects.
Implement produce for the commit log adapter and provide some test coverage. Also, use the NonZeroUsize type to express capacity, inline with what the cache requires.
Provide the ability to perform a side-effect after recovery has completed, and beef up the tests to test for this.
Eliminate cloning by using references for the entity id. Should result in a massive speed up.
Copy link
Member

@patriknw patriknw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

/// are no events sourced, or if it’s a new entity with a previously unused EntityId.
/// Any required side effects should be performed once recovery has completed by
/// overriding this method.
async fn on_recovery_completed(&self, _context: &Context, _state: &Self::State) {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

if let Ok(mut records) = records {
Ok(Box::pin(stream!({
while let Some(record) = records.next().await {
if &record.entity_id == entity_id {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An optimization could be if we could read the record entity_id without deserializing the payload. Then it would be more efficient to scan for a single entity_id.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah - that's a good idea. I'll do that as a separate PR.

@huntc huntc merged commit 016ff27 into main Aug 14, 2023
1 check passed
@huntc huntc deleted the lru-cache branch August 14, 2023 06:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants