-
Notifications
You must be signed in to change notification settings - Fork 15
Labels
ensapiENSApi relatedENSApi relatedensdbENSDb relatedENSDb relatedensindexerENSIndexer relatedENSIndexer related
Milestone
Description
Background
Currently:
- ENSIndexer exposes an API for indexing status and for its config
- ENSApi directly sends API calls to ENSIndexer to get its indexing status and config
- ENSApi uses SWR caching to remember the latest indexing status and config from ENSIndexer, such that ENSApi can survive crashes of ENSIndexer if and only if the ENSApi instance was able to successfully fetch these values from ENSIndexer during the lifecycle of the ENSApi process instance.
- ... Therefore: if ENSIndexer is crashed and ENSApi is restarted / launched, the new ENSApi currently will also fail to start. This would be a bad situation and we want to ensure it can't impact ENSNode deployments.
Goals
- Ensure ENSAPI can survive situations where ENSIndexer is down and ENSApi is restarted.
- Update ENSApi and ENSIndexer so that they stop exchanging the config and indexing status via API calls to ENSIndexer and instead they exchange this state exclusively through ENSDb. Here, ENSIndexer should push this state into ENSDb, while ENSApi should pull this state from ENSDb.
- Unblock the next phase of advancements on ENSAnalytics. More specifically, as a separate future goal, we want to transition the
ens-referralspackage out of the ENSNode repo and into theens-referralsrepo (which would be converted into a monorepo). Then, in theens-referralsrepo, we would want to create a new backend service for the leaderboard APIs that would be the first example of a custom app that would build on top of ENSDb and expose a tailored API built specifically for the needs of that app. This would allow us to transition all of the ENSAnalytics out of ENSNode and into this new custom app in theens-referralsrepo. Before we take all of these actions though it will be important that we first action the goals described in this issue so that there is a mature mechanism for an app to build custom APIs on top of ENSDb and to integrate with the indexing status and config stored in ENSDb. Related issue: Transition ENSAnalytics out of ENSApi #1352 - Protect ENSNode operators against a scenario where they have all ENSNode services up and running. Then imagine they keep ENSApi up and running while terminating ENSIndexer, wiping the configured
DATABASE_SCHEMA, and then starting a new ENSIndexer with config changes that are incompatible with the config that has been cached into memory by ENSApi. The logic proposed here aims to ensure that a max of 1 minute might exist where an ENSApi instance is attached to an incompatibleDATABASE_SCHEMAwithout knowing it. - Create a new
ENSDbClientclass that encapsulates logic for the following in a way that would be nicely reusable across apps building on top of ENSDb, including ENSApi and the future app described above in goal 3.- Manages
SWRCachethat read both the config and indexing status from aDATABASE_SCHEMAin ENSDb. - Enforcing that the indexing status and config objects that it caches are compatible. Ex: the chain ids perfectly align. Etc.
- Provides a helper function such as
isHealthythat gives a simple mechanism to identify if both a config and indexing status are held in memory and compatible with each other.
- Manages
- Improve the startup sequence of ENSApi such that it doesn't crash itself just because it is waiting on ENSIndexer to successfully initialize itself. Instead, it should patiently wait. Related issue: ENSApi & ENSIndexer re-try mechanism for long starting dependency (Render) #1303
- Update the logic for the
/healthendpoint in ENSApi such that it considers itself "unhealthy" if theENSDbClient.isHealthyis false.
- Update the logic for the
Non-Goals
- We should not remove the config or indexing status APIs from ENSIndexer. I believe all of our current usage of these APIs should be removed as a result of the changes described here, but I think it's best to keep these APIs living in ENSIndexer anyway as maybe there will be some special reason for them in the future that we cannot predict now.
Goals
- ENSIndexer
- Each time it starts it should:
- Check if a config has already been saved into the configured
DATABASE_SCHEMA. If so, read it from theDATABASE_SCHEMAand verify that it is compatible with the config object it has built in memory. If it is not compatible, refuse to start and provide a meaningful error message. - If no config has been saved into the configured
DATABASE_SCHEMAyet, save it there.
- Check if a config has already been saved into the configured
- At a frequent time interval (ex: maybe once per second?):
- Build a new indexing status snapshot in memory. If this fails for some reason, log the error and do nothing for this iteration of the asynchronous background loop.
- Is the omnichain indexing status in that snapshot
OmnichainIndexingStatusSnapshotUnstarted? If so, log the error and do nothing for this iteration of the asynchronous background loop. - Upsert the indexing status snapshot into the
DATABASE_SCHEMA.
- Each time it starts it should:
- ENSApi
- Update our logic for
SWRCacheso we update the signature of thefnsuch that it optionally receives a copy of whatever the latest cached value is as input. (Optionally meaning that if no value is already cached it receives undefined, but if a value is already cached it receives that value). This way thefncan internally decide special logic it may want to perform as a function of whatever the already cached value is. The purpose of this idea will be explained below. - Each time ENSApi starts it should:
- Build a SWRCache for reading the config from the configured
DATABASE_SCHEMA. This should proactively initialize itself and proactively revalidate itself once per minute.- The
fnshould work to read the config from the configuredDATABASE_SCHEMAand then validate / deserialize it. Anytime this fetch or validation / deserialization fails, log the error. - The
fnshould make use of the idea described above for thefnto optionally receive a copy of whatever the latest cached value as input was. More specifically, each time a new config value is built in memory (not yet returned fromfn) this function should compare that the config has not changed in a way that would be incompatible. In other words, changing a RPC endpoint is an example of a compatible change, however, changing the indexed ENS namespace is an example of an incompatible change. All transitions from no cached result -> cached result would pass this check, this check is purely for validating the transition from cached result A -> cached result B. If a config change is incompatible, ENSApi should forcefully terminate itself (open to other suggestions).
- The
- Build a SWRCache for the latest indexing status snapshot. But now the
fnassociated with this should work to read the indexing status snapshot from theDATABASE_SCHEMArather than reading the latest indexing status snapshot from direct API calls to ENSApi. If no indexing status snapshot is found in theDATABASE_SCHEMAthen log an error. If it is found, validate it. If validation / deserialization fails, log an error. If it is found and all validation / deserialization succeeds, compare the indexing status against the config as read from the SWRCache that manages the config. If the config is not cached yet, log a message. If the config is cached, validate that the new indexing status is compatible with the config. For example, all the chain ids should match up perfectly. Etc. If the new indexing status is compatible, successfully cached it. - store the indexing status in a proactively revalidating SWRCache. need to persist/cache the ensindexerpublicconfig to database so ensapi can survive restarts without ensindexer availability
- Consider itself "unhealthy" until both its SWRCacheIf ENSApi it is not found log an error and terminate. If it is found, validate it. If validation / deserialization fails, log an error and terminate. If it is found and all validation / deserialization succeeds, log the config it will be using to the console and store the cached config in memory indefinitely for the remaining lifecycle of the ENSApi process instance.
- Build a SWRCache for reading the config from the configured
- Remove the following environment variables from ENSApi:
ENSINDEXER_URL
- Update our logic for
Metadata
Metadata
Assignees
Labels
ensapiENSApi relatedENSApi relatedensdbENSDb relatedENSDb relatedensindexerENSIndexer relatedENSIndexer related
Type
Projects
Status
In Progress