-
Notifications
You must be signed in to change notification settings - Fork 0
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: persisting strategy registry into db #40
base: dev
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GJ ser, this is a lot of work. Just small comments :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
god
DatabaseStrategyRegistry, | ||
IEventsRegistry, | ||
InMemoryCachedStrategyRegistry, | ||
} from "@grants-stack-indexer/data-flow/dist/src/internal.js"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is pointing to dist
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed: aa3ee27
@@ -13,6 +18,7 @@ import { | |||
KyselyDonationRepository, | |||
KyselyProjectRepository, | |||
KyselyRoundRepository, | |||
KyselyStrategyRepository, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
StrategyRegistryRepository
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new Logger({ className: "InMemoryCachedStrategyRegistry" }), | ||
new DatabaseStrategyRegistry( | ||
new Logger({ className: "DatabaseStrategyRegistry" }), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a little concerned about using multiple logger instances. I think it adds tons of overhead, think about a logger that sends logs to a server or prints all the logs into a file, for each instance you will have a connection (1st case) or a dedicated file (2nd case) correct me if iam wrong pls.
i would love to hear @0xyaco 's opinion about having multiple logger instances across the application
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mmm i see what you're pointing, we can better discuss it on the Error handling and Logging milestone but a solution could be a Context object on each call so we know which file or chain emitted a log?
packages/data-flow/README.md
Outdated
|
||
The `StrategyRegistry` stores strategy IDs to populate strategy events with them given the Strategy address. | ||
There are 3 implementations: | ||
|
||
- `InMemoryStrategyRegistry`: stores map in-memory |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe we should get rid of this one since it will be no longer used and adds noise here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okii makes sense
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed: aa3ee27
private readonly strategyRegistry: IStrategyRegistry, | ||
cache: Map<ChainId, Map<Address, Strategy>>, | ||
) { | ||
this.cache = structuredClone(cache); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't know that structuredClone
exist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to pass cache as parameter instead of having it contained in the class ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the cache is built in the static async constructor, for the class to be instantiated with the pre-filled cache elements, it needs to receive it in constructor
strategyRegistry: IStrategyRegistry, | ||
): Promise<InMemoryCachedStrategyRegistry> { | ||
const strategies = await strategyRegistry.getStrategies(); | ||
const cache = new Map<ChainId, Map<Address, Strategy>>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think here is my answer xd
@@ -41,9 +37,13 @@ pnpm install | |||
To apply all pending migrations: | |||
|
|||
```bash | |||
pnpm script:db:migrate | |||
pnpm db:migrate --schema=schema_name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we rollback this ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nono, user can still name a different schema if they want (i mean i think flexibility is cool to have) but default is public
schema
Optional arguments: | ||
|
||
- `--schema` or `-s`: Database schema name where migrations are applied. Defaults to `public`. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is no longer needed right ?
@@ -57,7 +57,7 @@ This will: | |||
To completely reset the database schema: | |||
|
|||
```bash | |||
pnpm script:db:reset | |||
pnpm db:reset --schema=schema_name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
@@ -33,6 +38,27 @@ vi.mock("@grants-stack-indexer/indexer-client", () => ({ | |||
EnvioIndexerClient: vi.fn(), | |||
})); | |||
|
|||
// Update the mock to handle async initialization |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a TODO?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not a TODO, neither a needed comment. cursor wrote it my bad
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*/ | ||
saveStrategyId(strategyAddress: Address, strategyId: Hex): Promise<void>; | ||
getStrategies(params?: { handled?: boolean; chainId?: ChainId }): Promise<Strategy[]>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to what Kenji said might even consider having a separate filterStrategies
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
like a different method? i'm not a big fan of this approach where custom actions are mapped to specific methods. i think filters are optional conditions applied to the general case query here
this.cache = structuredClone(cache); | ||
} | ||
|
||
async getStrategies(params?: { handled?: boolean; chainId?: ChainId }): Promise<Strategy[]> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe consider separating this out into getAllStrategies and get filteredStrategies rather than the optional params
return strategy; | ||
} | ||
|
||
async saveStrategyId( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if you need inherit docs comment in this file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing yeah thanks sir
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*/ | ||
export class InMemoryStrategyRegistry implements IStrategyRegistry { | ||
private strategiesMap: Map<ChainId, Map<Address, Strategy>> = new Map(); | ||
constructor(private logger: ILogger) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be be initializing a logger/getting the instance here? 🤔
) {} | ||
|
||
async getStrategyByChainIdAndAddress( | ||
chainId: ChainId, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Docs for this file/inherit docs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
const schema = getSchemaName(db.schema); | ||
|
||
console.log("schema", schema); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this console log intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -2,7 +2,6 @@ import { z } from "zod"; | |||
|
|||
const dbEnvSchema = z.object({ | |||
DATABASE_URL: z.string().url(), | |||
DATABASE_SCHEMA: z.string().min(1), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's optional maybe could leave it in with .optional() just to validate that the user knows it's a schema name and doesn't try adding an actual schema
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this one is no longer needed, schema is now script arg not an env variable, that's the difference. no longer a secret xd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bien
🤖 Linear
Closes GIT-185
Description
We want to persist
strategyId
s onPoolCreated
events so we could later pre-process all of the past events when we implement in code a new Strategy Handler.StrategyRepository
to store seen strategyIds with their corresponding address and whether it was handled or notDBStrategyRegistry
that interfaces with the repoDBStrategyRegistry
(InMemoryCachedStrategyRegistry)Checklist before requesting a review