-
Notifications
You must be signed in to change notification settings - Fork 3
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: Auto migrate indexers to Control Plane #527
Conversation
17cf449
to
9626c7c
Compare
555df8a
to
92e9d54
Compare
6d8a4b6
to
84dd294
Compare
|
||
// `redis::transaction`s currently don't work with async connections, so we have to create a _new_ | ||
// blocking connection to atmoically update a value. | ||
pub fn atomic_update<K, O, N, F>(redis_url: &str, key: K, update_fn: F) -> anyhow::Result<()> |
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 isn't ideal - blocking code blocks all async code, but given this happens infrequently, and is only temporary it should be ok.
use crate::registry::IndexerConfig; | ||
|
||
#[tokio::test] | ||
async fn ignores_migrated_indexers() { |
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.
Could definitely expand on these cases but as Redis is mocked it wouldn't provide much benefit, the time would be better spent testing in Dev.
#[derive(serde::Deserialize, serde::Serialize, Debug)] | ||
struct DenylistEntry { | ||
account_id: AccountId, | ||
v1_ack: bool, |
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.
Haven't included migrated
/failed
because they're not needed - serde
will just ignore them.
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.
LGTM! Really cool work on this!
) -> anyhow::Result<()> { | ||
tracing::info!("Migrating account {}", account_id); | ||
|
||
for (_, indexer_config) in indexers.iter() { |
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.
Really cool workflow in this! I can see how it's friendly to both a re-run (picking up after manual fix of failed migration) and running for the first time.
|
||
match account_in_deny_list { | ||
Some(account_in_deny_list) => { | ||
tracing::info!( |
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 will be printed on every ignored indexer for every block coordinator publishes right? This would probably clog up the logs. Maybe its better to collect either ignored or not-ignored indexers in a list and print it all together at the end, instead.
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.
No - because the registry is mutated as we go, only "new" removals will be logged
This PR builds on the Redis
allowlist
to auto migrate indexers from the existing infrastructure to the Control Plane. An account migration requires coordination between both the V1 and V2 architecture - the indexer must be removed/ignored from V1, and then correctly configured within V2.Allowlist shape
Each
allowlist
entry now contain the following properties:Coordinator V1
For Coordinator V1, the
allowlist
is really a Denylist, the code/types have therefore been named as such. Accounts within the "denylist" should be ignored completely by V1. Because we cannot guarantee the timing of when this "ignore" actually happens, a flag (v1_ack
) will be set from V1. V2 will only take over once this flag has been set.Accounts within the "denylist" will be filtered out of the in-memory registry. Any new indexer "registrations" will also be ignored. In-progress historical backfills haven't been considered as we'll disable this functionality anyway.
Coordinator V2
Once acknowledged by V1, Coordinator V2 will attempt to migrate all functions under the relevant account. The steps for migration are:
streams
set - preventing Runner from starting these indexers implicitlystreams
setOnce migrated, accounts which have
v1_ack && migrated && !failed
will be exposed to the control loop, prompting V2 to act on these indexers.migrated
flagFor now, the
migrated
flag will not be set on success, preventing V2 from running the indexer on the new architecture. There are some issues around V2 continuing from the right block correctly, so it's best to not run them for now. This allows us to test the migration in isolation, not worrying about what V2 does after that. I'll add this logic back in once #536 is complete.failed
flagIf any part of the migration fails, the
failed
flag will be set for that account. It would take a significant amount of time to cover all the edge cases in code so it would be faster to just set this flag to ignore the account, fix the migration manually and then reset thefailed
flag.