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: Auto migrate indexers to Control Plane #527

Merged
merged 27 commits into from
Feb 6, 2024
Merged

Conversation

morgsmccauley
Copy link
Collaborator

@morgsmccauley morgsmccauley commented Jan 25, 2024

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:

pub struct AllowlistEntry {
    account_id: AccountId, // The account which should be migrated
    v1_ack: bool,          // True if Coordinator V1 has acknowledged the entry
    migrated: bool,        // True if the migration was successful
    failed: bool,          // True if the migration failed
}

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:

  1. Remove the streams from the Redis streams set - preventing Runner from starting these indexers implicitly
  2. Stop the existing V1 executors which have already been started via the streams set
  3. Merge the existing historical (if it exists) and real-time streams

Once migrated, accounts which have v1_ack && migrated && !failed will be exposed to the control loop, prompting V2 to act on these indexers.

migrated flag

For 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 flag

If 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 the failed flag.

@morgsmccauley morgsmccauley linked an issue Jan 25, 2024 that may be closed by this pull request
@morgsmccauley morgsmccauley force-pushed the feat/v2-migration branch 3 times, most recently from 17cf449 to 9626c7c Compare January 31, 2024 19:37
@morgsmccauley morgsmccauley changed the title feat/v2 migration feat: Auto migrate indexers to Control Plane Feb 2, 2024
@morgsmccauley morgsmccauley marked this pull request as ready for review February 2, 2024 03:26
@morgsmccauley morgsmccauley requested a review from a team as a code owner February 2, 2024 03:26

// `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<()>
Copy link
Collaborator Author

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() {
Copy link
Collaborator Author

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,
Copy link
Collaborator Author

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.

Copy link
Collaborator

@darunrs darunrs left a 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() {
Copy link
Collaborator

@darunrs darunrs Feb 5, 2024

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!(
Copy link
Collaborator

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.

Copy link
Collaborator Author

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

@morgsmccauley morgsmccauley merged commit 9ef1f29 into main Feb 6, 2024
8 checks passed
@morgsmccauley morgsmccauley deleted the feat/v2-migration branch February 6, 2024 19:07
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.

Migrate Indexers to Control Plane
2 participants