Package com.linkedin.venice.hooks
Class StoreLifecycleHooks
- java.lang.Object
-
- com.linkedin.venice.hooks.StoreLifecycleHooks
-
public abstract class StoreLifecycleHooks extends java.lang.Object
This interface defines a set of lifecycle events for stores and their store-versions.
Pre-hooks and post-hooks
Most events have a pre- and post- variant, all pre-hooks provide an option to control the outcome of the event (e.g. to abort it), while only some post-hooks provide such flow control, and others are intended for informational purposes only.
Barring unforeseen bugs or failures, the#postEndOfPushJob(String, String, VeniceProperties, VeniceProperties, PushJobDetailsStatus)
post-hook should always be executed for all push jobs, regardless of whether the job succeeded or not. For all other post-hooks, the invocation of the hook assumes that the corresponding step succeeded.
Failures and timeouts
All exceptions thrown from any of the hooks are swallowed, logged and emitted as metrics. In the case of pre-hooks, exceptions will be treated as an indication to proceed. If a hook implementer wishes to prevent an operation from proceeding if the hook fails or hangs, then it is the implementer's responsibility to wrap the whole hook's logic into a try-catch or similar safeguard, and to return the signal to abort in case of failure.
Likewise, the framework executing these hooks is allowed to impose a maximum duration on the hook's runtime, and to proceed forward in case of timeouts, so hooks should not block for extended durations. Note that some hooks allow for deferring their control flow decisions, viaStoreVersionLifecycleEventOutcome.WAIT
, in which case the hooks framework will interrogate the hook again after some interval elapsed. This provides a first-class mechanism for stalling the operation in case the hook needs more time to make its decision. If a hook implementer wishes to ensure that stalling behavior, they should prevent the hook implementation from timing out, and return the signal to wait in cases where their custom logic is taking an abnormally long time to finish.
Instance creation, state and lifetime
AllStoreLifecycleHooks
classes need to be registered at startup time instances, and will be created by reflection via theStoreLifecycleHooks
constructor. If multiple hooks are registered, then they will be invoked in the order they appear in the config. The hooks framework can, at its discretion, create, reuse and close instances whenever. Related hooks (such as pre- and post-hooks of a certain event type) are not guaranteed to be invoked on the same hook instance, or even in the same JVM. Therefore, any state which a hook instance accumulates should be strictly limited to best-effort optimizations, e.g. establishing a connection to another service, and keeping that connection (or connection pool) open is fine. All state which is significant for the correctness of the hook should be persisted outside the hooks' runtime memory. Likewise, no state should ever be persisted in the JVM's local filesystem.
Store-level hooks configs
The store config contains a bag of arbitrary properties which can be used to override the behavior of hooks. This bag is passed into all hooks. Note that there is just a single bag of properties per store, therefore the configs of all registered hooks must coexist within that bag. As such, namespacing is strongly recommended, so that different hooks don't conflict with each other.
Cardinality
Each hook is annotated with a cardinality, providing a rough indication of how often the hook can be expected to be invoked.
Thread safety
Hook functions can be invoked concurrently and so hook implementations are expected to be thread-safe.
However, the hooks framework guarantees to call hooks one at a time for a given store, so even if multiple hooks for a given store simultaneously become eligible to be called, their invocation will be serialized.
-
-
Constructor Summary
Constructors Constructor Description StoreLifecycleHooks(VeniceProperties defaultConfigs)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description protected VeniceProperties
getDefaultConfigs()
void
postEndOfPushJob(java.lang.String clusterName, java.lang.String storeName, VeniceProperties storeHooksConfigs, PushJobDetailsStatus terminalStatus)
Invoked when a job ends, either because it completed, had an error, or was killed (as indicated by thePushJobDetailsStatus
parameter).
Cardinality: once per push job.void
postSchemaRegistration(java.lang.String clusterName, java.lang.String storeName, java.lang.String newSchema, java.util.Map<java.lang.Integer,java.lang.String> existingSchemas, VeniceProperties storeHooksConfigs)
Invoked after registering a new schema.
Cardinality: once per successful schema registration.void
postStartOfPushJob(java.lang.String clusterName, java.lang.String storeName, VeniceProperties storeHooksConfigs)
Invoked after starting a new job (i.e.StoreVersionLifecycleEventOutcome
postStartOfStoreVersionIngestionForDaVinci(java.lang.String clusterName, java.lang.String storeName, int versionNumber, java.lang.String regionName, Lazy<JobStatusQueryResponse> jobStatus, VeniceProperties storeHooksConfigs)
Invoked after informing Da Vinci Clients that they may start to ingest a new store-version.
It is important to note that:
1.void
postStoreVersionCreation(java.lang.String clusterName, java.lang.String storeName, int versionNumber, java.lang.String regionName, VeniceProperties storeHooksConfigs)
Invoked after creating a store-version in a given region, which means the following actions succeeded:
- AllpreStoreVersionCreation(String, String, int, String, Lazy, VeniceProperties)
hooks.
- Creation of the store-version's dedicated resources (pub sub topic, Helix resource).
- Server replicas have begun ingesting.
Cardinality: once per successful store-version creation per region.void
postStoreVersionLeaderReplication(java.lang.String clusterName, java.lang.String storeName, int versionNumber, java.lang.String regionName, VeniceProperties storeHooksConfigs)
Invoked after all leader replicas of a store-version within a single region have completed, which means the data replication to that region is done.
Cardinality: once per successfully-replicated store-version per region.StoreVersionLifecycleEventOutcome
postStoreVersionSwap(java.lang.String clusterName, java.lang.String storeName, int versionNumber, java.lang.String regionName, Lazy<JobStatusQueryResponse> jobStatus, VeniceProperties storeHooksConfigs)
Invoked after swapping read traffic for servers.
Cardinality: once per store-version per region which has successfully swapped.StoreVersionLifecycleEventOutcome
preEndOfPushJob(java.lang.String clusterName, java.lang.String storeName, Lazy<JobStatusQueryResponse> jobStatus, VeniceProperties storeHooksConfigs)
Invoked prior to ending a job.StoreLifecycleEventOutcome
preSchemaRegistration(java.lang.String clusterName, java.lang.String storeName, java.lang.String newSchema, java.util.Map<java.lang.Integer,java.lang.String> existingSchemas, VeniceProperties storeHooksConfigs)
Invoked prior to registering a new schema, but after standard checks already succeeded.StoreLifecycleEventOutcome
preStartOfPushJob(java.lang.String clusterName, java.lang.String storeName, VeniceProperties storeHooksConfigs)
Invoked prior to starting a new job.StoreVersionLifecycleEventOutcome
preStartOfStoreVersionIngestionForDaVinci(java.lang.String clusterName, java.lang.String storeName, int versionNumber, java.lang.String regionName, Lazy<JobStatusQueryResponse> jobStatus, VeniceProperties storeHooksConfigs)
Invoked prior to informing Da Vinci Clients about starting to ingest a new store-version.
Cardinality: once per store-version per region.StoreVersionLifecycleEventOutcome
preStoreVersionCreation(java.lang.String clusterName, java.lang.String storeName, int versionNumber, java.lang.String regionName, Lazy<JobStatusQueryResponse> jobStatus, VeniceProperties storeHooksConfigs)
Invoked prior to creating a store-version in a given region.
Cardinality: once per store-version creation attempt per region, assuming no previous failures.StoreVersionLifecycleEventOutcome
preStoreVersionSwap(java.lang.String clusterName, java.lang.String storeName, int versionNumber, java.lang.String regionName, Lazy<JobStatusQueryResponse> jobStatus, VeniceProperties storeHooksConfigs)
Invoked prior to swapping read traffic for servers.StoreLifecycleEventOutcome
validateHookConfig(java.lang.String clusterName, java.lang.String storeName, java.lang.String configKey, java.lang.String configValue)
Invoked prior to updating a store's config with a given hook config.
-
-
-
Constructor Detail
-
StoreLifecycleHooks
public StoreLifecycleHooks(VeniceProperties defaultConfigs)
-
-
Method Detail
-
getDefaultConfigs
protected VeniceProperties getDefaultConfigs()
-
validateHookConfig
public StoreLifecycleEventOutcome validateHookConfig(java.lang.String clusterName, java.lang.String storeName, java.lang.String configKey, java.lang.String configValue)
Invoked prior to updating a store's config with a given hook config. If the hook implementation recognizes the config key and the associated config value is valid (e.g. can be parsed or cast to the correct type), then it should returnStoreLifecycleEventOutcome.PROCEED
, otherwise it should returnStoreLifecycleEventOutcome.ABORT
.
Note that there is a single hook config bag shared by all registered hooks, and so config keys should be namespaced in order to avoid collisions (unless a given config key is intended to control similar behavior in many hooks).
The hooks framework will reject the store config update if all registered hooks return the ABORT signal, and will accept it if at least one registered hook returns the PROCEED signal.
Cardinality: once per config key/value pair included in a store update command.
-
preStartOfPushJob
public StoreLifecycleEventOutcome preStartOfPushJob(java.lang.String clusterName, java.lang.String storeName, VeniceProperties storeHooksConfigs)
Invoked prior to starting a new job. The hook has the option of aborting the job.
N.B.: this hook returns aStoreLifecycleEventOutcome
, and not aStoreVersionLifecycleEventOutcome
, because the new store-version is not created yet at the start of the push job.
Cardinality: once per push job.
-
postStartOfPushJob
public void postStartOfPushJob(java.lang.String clusterName, java.lang.String storeName, VeniceProperties storeHooksConfigs)
Invoked after starting a new job (i.e. if allpreStartOfPushJob(String, String, VeniceProperties)
hooks succeeded).
Cardinality: once per push job, assuming no previous failures.
-
preSchemaRegistration
public StoreLifecycleEventOutcome preSchemaRegistration(java.lang.String clusterName, java.lang.String storeName, java.lang.String newSchema, java.util.Map<java.lang.Integer,java.lang.String> existingSchemas, VeniceProperties storeHooksConfigs)
Invoked prior to registering a new schema, but after standard checks already succeeded. The hook has the option of aborting the registration (which causes the whole push job to abort as well, if this is happening as part of a job's auto-registration step).
Cardinality: once per schema registration attempt.
-
postSchemaRegistration
public void postSchemaRegistration(java.lang.String clusterName, java.lang.String storeName, java.lang.String newSchema, java.util.Map<java.lang.Integer,java.lang.String> existingSchemas, VeniceProperties storeHooksConfigs)
Invoked after registering a new schema.
Cardinality: once per successful schema registration.
-
preStoreVersionCreation
public StoreVersionLifecycleEventOutcome preStoreVersionCreation(java.lang.String clusterName, java.lang.String storeName, int versionNumber, java.lang.String regionName, Lazy<JobStatusQueryResponse> jobStatus, VeniceProperties storeHooksConfigs)
Invoked prior to creating a store-version in a given region.
Cardinality: once per store-version creation attempt per region, assuming no previous failures.
-
postStoreVersionCreation
public void postStoreVersionCreation(java.lang.String clusterName, java.lang.String storeName, int versionNumber, java.lang.String regionName, VeniceProperties storeHooksConfigs)
Invoked after creating a store-version in a given region, which means the following actions succeeded:
- AllpreStoreVersionCreation(String, String, int, String, Lazy, VeniceProperties)
hooks.
- Creation of the store-version's dedicated resources (pub sub topic, Helix resource).
- Server replicas have begun ingesting.
Cardinality: once per successful store-version creation per region.
-
preStartOfStoreVersionIngestionForDaVinci
public StoreVersionLifecycleEventOutcome preStartOfStoreVersionIngestionForDaVinci(java.lang.String clusterName, java.lang.String storeName, int versionNumber, java.lang.String regionName, Lazy<JobStatusQueryResponse> jobStatus, VeniceProperties storeHooksConfigs)
Invoked prior to informing Da Vinci Clients about starting to ingest a new store-version.
Cardinality: once per store-version per region.
-
postStartOfStoreVersionIngestionForDaVinci
public StoreVersionLifecycleEventOutcome postStartOfStoreVersionIngestionForDaVinci(java.lang.String clusterName, java.lang.String storeName, int versionNumber, java.lang.String regionName, Lazy<JobStatusQueryResponse> jobStatus, VeniceProperties storeHooksConfigs)
Invoked after informing Da Vinci Clients that they may start to ingest a new store-version.
It is important to note that:
1. DVC will not necessarily have started ingesting when this hook is invoked, since that process happens asynchronously after notifying.
2. DVC will proceed to swap for serving reads on a per-instance basis as soon the ingestion completes. At this time there is no support for deferring the swap until all instances of a region have completed (as is the case for servers).
Cardinality: once per store-version per region.
-
postStoreVersionLeaderReplication
public void postStoreVersionLeaderReplication(java.lang.String clusterName, java.lang.String storeName, int versionNumber, java.lang.String regionName, VeniceProperties storeHooksConfigs)
Invoked after all leader replicas of a store-version within a single region have completed, which means the data replication to that region is done.
Cardinality: once per successfully-replicated store-version per region.
-
preStoreVersionSwap
public StoreVersionLifecycleEventOutcome preStoreVersionSwap(java.lang.String clusterName, java.lang.String storeName, int versionNumber, java.lang.String regionName, Lazy<JobStatusQueryResponse> jobStatus, VeniceProperties storeHooksConfigs)
Invoked prior to swapping read traffic for servers. Specifically, this means:
- Leader replication is complete.
- A sufficient number of followers have completed their ingestion.
- All online Da Vinci Client instances have already swapped their reads to the new store-version.
Cardinality: once per store-version per region which is ready to swap.
-
postStoreVersionSwap
public StoreVersionLifecycleEventOutcome postStoreVersionSwap(java.lang.String clusterName, java.lang.String storeName, int versionNumber, java.lang.String regionName, Lazy<JobStatusQueryResponse> jobStatus, VeniceProperties storeHooksConfigs)
Invoked after swapping read traffic for servers.
Cardinality: once per store-version per region which has successfully swapped.
-
preEndOfPushJob
public StoreVersionLifecycleEventOutcome preEndOfPushJob(java.lang.String clusterName, java.lang.String storeName, Lazy<JobStatusQueryResponse> jobStatus, VeniceProperties storeHooksConfigs)
Invoked prior to ending a job. Specifically, this means that the new store-version was swapped in all regions. This is a final chance to control the job and its associated store-version prior to termination.
Cardinality: once per push job.
-
postEndOfPushJob
public void postEndOfPushJob(java.lang.String clusterName, java.lang.String storeName, VeniceProperties storeHooksConfigs, PushJobDetailsStatus terminalStatus)
Invoked when a job ends, either because it completed, had an error, or was killed (as indicated by thePushJobDetailsStatus
parameter).
Cardinality: once per push job.
-
-