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

feat: db event registry repository #42

Merged
merged 7 commits into from
Dec 20, 2024
Merged

Conversation

0xnigir1
Copy link
Collaborator

@0xnigir1 0xnigir1 commented Dec 17, 2024

🤖 Linear

Closes GIT-188

Description

We want to persist the last event processed for each chain so we can safely stop and resume the indexer from where we left off.

  • Create EventRegistryRepository to store the last processed event per chain
  • DBEventsRegistry that interfaces with the repo
  • a Proxied version that caches in memory and uses the DBEventRegistry (InMemoryCachedEventRegistry) and loads into memory the data stored on DB on init
  • update Processing app to use the InMemoryCachedEventRegistry
  • add the migration to create the table events for DBEventsRegistry repo

Checklist before requesting a review

  • I have conducted a self-review of my code.
  • I have conducted a QA.
  • If it is a core feature, I have included comprehensive tests.

@0xnigir1 0xnigir1 self-assigned this Dec 17, 2024
Copy link

linear bot commented Dec 17, 2024

Copy link
Collaborator

@0xkenj1 0xkenj1 left a comment

Choose a reason for hiding this comment

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

just a tiny comment , gj ser! 🥳

Comment on lines +23 to +25
registriesRepositories: {
eventRegistryRepository: IEventRegistryRepository;
strategyRegistryRepository: IStrategyRegistryRepository;
Copy link
Collaborator

Choose a reason for hiding this comment

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

i think the previous way was ok. I...Registry should be de dependency not I...RegistryRepository. Lmk if iam missing something

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 changed the way it works by creating an instance per chain but using the same repository, since it's not really necessary to load into memory the lastProcessedEvent of another chain (if we deploy a container per chain, this is more obvious to see).

if this makes sense, the same change applies for strategies (we create an instance per chain) but didn't want to mix and make the change for StrategyRegistry too. if we go for this approach, i'll make the change in another PR

if smth it's not clear, we can discuss it offline 😄

Comment on lines +49 to +59
const strategyRegistry = await InMemoryCachedStrategyRegistry.initialize(
new Logger({ className: "InMemoryCachedStrategyRegistry" }),
new DatabaseStrategyRegistry(
new Logger({ className: "DatabaseStrategyRegistry" }),
strategyRegistryRepository,
),
);
const eventsRegistry = new DatabaseEventRegistry(
new Logger({ className: "DatabaseEventRegistry" }),
eventRegistryRepository,
);
Copy link
Collaborator

Choose a reason for hiding this comment

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

is there a reason why you are doing this outside the SharedDependenciesService ?

Copy link
Collaborator

Choose a reason for hiding this comment

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

sweet

this.cache.set(chainId, { ...event, chainId });
}

/**
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
/**

xd

Copy link
Collaborator

@0xyaco 0xyaco left a comment

Choose a reason for hiding this comment

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

Mostly minor naming stuff, pretty complete PR

private constructor(
private readonly logger: ILogger,
private readonly eventRegistry: IEventsRegistry,
cache: Map<ChainId, ProcessedEvent>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Extremely minor, but maybe renaming it to initialEntries or initialCache and making it optional would make this a little bit more explanatory?

Suggested change
cache: Map<ChainId, ProcessedEvent>,
initialCache?: Map<ChainId, ProcessedEvent>,

Nothing serious though, feel free to dismiss this comment if you prefer it the way it is.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

the goal of this class this is a proxied cache so it always is initialized with a pre-filled cache that fallbacks to the main registry implementation and given that constructor is private i think it's the same to have it optional or not

Comment on lines +22 to +25
const cachedEvent = this.cache.get(chainId);
if (cachedEvent) {
return cachedEvent;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I've got no idea on the business logic but worth asking; should you include some kind of TTL for this 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.

is not really necessary since we're processing one event at time and saving on each iteration, tbh here we just save a really few calls to the DB

// Verify no additional calls to underlying registry
expect(mockEventRegistry.getLastProcessedEvent).toHaveBeenCalledTimes(1);
});

Copy link
Collaborator

Choose a reason for hiding this comment

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

What if the other registry fails while saving?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

that's a really good question sir

cc @0xkenj1 we can discuss it offline if this is is a retriable error or not

const CHAIN_ID_TYPE = "integer";

await db.schema
.createTable("events")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does using last_events as the table name fit better to this use case? It feels weird having a table named events with a chainId primary key.

Suggested change
.createTable("events")
.createTable("last_events")

@0xnigir1 0xnigir1 requested review from 0xyaco and 0xkenj1 December 19, 2024 16:11
@0xnigir1 0xnigir1 merged commit 4b4c594 into dev Dec 20, 2024
6 checks passed
@0xnigir1 0xnigir1 deleted the feat/db-event-registry-repository branch December 20, 2024 14:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants