Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Event Triggers
Event triggers are like ordinary SQL triggers, except instead of calling a SQL procedure, they call a webhook. The event delivery mechanism involves coordination between both the database and graphql-engine: only the SQL database knows when the events should fire, but only graphql-engine know how to actually deliver them.
Therefore, event triggers are implemented in two parts:
- Every event trigger is backed by a bona fide SQL trigger. When the SQL trigger fires, it creates a new record in the hdb_catalog.event_log table.
- Concurrently, a thread in graphql-engine monitors the hdb_catalog.event_log table for new events. When new event(s) are found, it uses the information (URL,payload and headers) stored in the event to deliver the event to the webhook.
The creation and deletion of SQL trigger itself is managed by the metadata DDL APIs (see Hasura.RQL.DDL.EventTrigger), so this module focuses on event delivery.
Most of the subtleties involve guaranteeing reliable delivery of events: we guarantee that every event will be delivered at least once, even if graphql-engine crashes. This means we have to record the state of each event in the database, and we have to retry failed requests at a regular (user-configurable) interval.
Synopsis
- data EventEngineCtx = EventEngineCtx {}
- defaultMaxEventThreads :: Refined Positive Int
- defaultFetchInterval :: DiffTime
- initEventEngineCtx :: MonadIO m => Refined Positive Int -> Refined NonNegative Milliseconds -> Refined NonNegative Int -> m EventEngineCtx
- saveLockedEventTriggerEvents :: MonadIO m => SourceName -> [EventId] -> TVar (HashMap SourceName (Set EventId)) -> m ()
- removeEventTriggerEventFromLockedEvents :: MonadIO m => SourceName -> EventId -> TVar (HashMap SourceName (Set EventId)) -> m ()
- createFetchedEventsStatsLogger :: MonadIO m => Logger Hasura -> m FetchedEventsStatsLogger
- closeFetchedEventsStatsLogger :: MonadIO m => Logger Hasura -> FetchedEventsStatsLogger -> m ()
- processEventQueue :: forall m. (MonadIO m, MonadBaseControl IO m, Forall (Pure m), MonadMask m, MonadTrace m, MonadGetPolicies m) => Logger Hasura -> FetchedEventsStatsLogger -> Manager -> IO SchemaCache -> IO EventEngineCtx -> TVar Int -> LockedEventsCtx -> ServerMetrics -> EventTriggerMetrics -> MaintenanceMode () -> m (Forever m)
- logQErr :: (MonadReader r m, Has (Logger Hasura) r, MonadIO m) => QErr -> m ()
Documentation
data EventEngineCtx Source #
See Note [Maintenance Mode]
initEventEngineCtx :: MonadIO m => Refined Positive Int -> Refined NonNegative Milliseconds -> Refined NonNegative Int -> m EventEngineCtx Source #
saveLockedEventTriggerEvents :: MonadIO m => SourceName -> [EventId] -> TVar (HashMap SourceName (Set EventId)) -> m () Source #
removeEventTriggerEventFromLockedEvents :: MonadIO m => SourceName -> EventId -> TVar (HashMap SourceName (Set EventId)) -> m () Source #
createFetchedEventsStatsLogger :: MonadIO m => Logger Hasura -> m FetchedEventsStatsLogger Source #
Logger to accumulate stats of fetched events over a period of time and log once using 'L.Logger L.Hasura'.
See
createStatsLogger
for more details.
closeFetchedEventsStatsLogger :: MonadIO m => Logger Hasura -> FetchedEventsStatsLogger -> m () Source #
Close the fetched events stats logger.
processEventQueue :: forall m. (MonadIO m, MonadBaseControl IO m, Forall (Pure m), MonadMask m, MonadTrace m, MonadGetPolicies m) => Logger Hasura -> FetchedEventsStatsLogger -> Manager -> IO SchemaCache -> IO EventEngineCtx -> TVar Int -> LockedEventsCtx -> ServerMetrics -> EventTriggerMetrics -> MaintenanceMode () -> m (Forever m) Source #
Service events from our in-DB queue.
There are a few competing concerns and constraints here; we want to... - fetch events in batches for lower DB pressure - don't fetch more than N at a time (since that can mean: space leak, less effective scale out, possible double sends for events we've checked out on exit (TODO clean shutdown procedure)) - try not to cause webhook workers to stall waiting on DB fetch - limit webhook HTTP concurrency per HASURA_GRAPHQL_EVENTS_HTTP_POOL_SIZE