mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-15 17:31:56 +03:00
server: recreate event triggers while migrating source catalog
GitOrigin-RevId: 9a07fec31fcdbe6ef3b96bb61c95e0dd544e7f50
This commit is contained in:
parent
bf629db930
commit
cd509a0036
@ -26,6 +26,7 @@ import Hasura.Backends.Postgres.SQL.Types
|
||||
import Hasura.Base.Error
|
||||
import Hasura.RQL.Types.Backend
|
||||
import Hasura.RQL.Types.Common
|
||||
import Hasura.RQL.Types.EventTrigger (RecreateEventTriggers (..))
|
||||
import Hasura.RQL.Types.Function
|
||||
import Hasura.RQL.Types.Source
|
||||
import Hasura.RQL.Types.Table
|
||||
@ -66,21 +67,24 @@ resolveDatabaseMetadata sourceConfig = runExceptT do
|
||||
pure $ ResolvedSource sourceConfig tablesMeta functionsMeta pgScalars
|
||||
|
||||
-- | Initialise catalog tables for a source, including those required by the event delivery subsystem.
|
||||
initCatalogForSource :: forall m . MonadTx m => MaintenanceMode -> UTCTime -> m ()
|
||||
initCatalogForSource
|
||||
:: forall m . MonadTx m => MaintenanceMode -> UTCTime -> m RecreateEventTriggers
|
||||
initCatalogForSource maintenanceMode migrationTime = do
|
||||
hdbCatalogExist <- doesSchemaExist "hdb_catalog"
|
||||
eventLogTableExist <- doesTableExist "hdb_catalog" "event_log"
|
||||
sourceVersionTableExist <- doesTableExist "hdb_catalog" "hdb_source_catalog_version"
|
||||
-- when maintenance mode is enabled, don't perform any migrations
|
||||
if | maintenanceMode == MaintenanceModeEnabled -> pure ()
|
||||
if | maintenanceMode == MaintenanceModeEnabled -> pure RETDoNothing
|
||||
-- Fresh database
|
||||
| not hdbCatalogExist -> liftTx do
|
||||
Q.unitQE defaultTxErrorHandler "CREATE SCHEMA hdb_catalog" () False
|
||||
enablePgcryptoExtension
|
||||
initPgSourceCatalog
|
||||
return RETDoNothing
|
||||
-- Only 'hdb_catalog' schema defined
|
||||
| not sourceVersionTableExist && not eventLogTableExist ->
|
||||
| not sourceVersionTableExist && not eventLogTableExist -> do
|
||||
liftTx initPgSourceCatalog
|
||||
return RETDoNothing
|
||||
-- Source is initialised by pre multisource support servers
|
||||
| not sourceVersionTableExist && eventLogTableExist -> do
|
||||
-- Update the Source Catalog to v43 to include the new migration
|
||||
@ -93,7 +97,8 @@ initCatalogForSource maintenanceMode migrationTime = do
|
||||
liftTx createVersionTable
|
||||
-- Migrate the catalog from initial version i.e '1'
|
||||
migrateSourceCatalogFrom "1"
|
||||
| otherwise -> migrateSourceCatalog
|
||||
return RETRecreate
|
||||
| otherwise -> migrateSourceCatalog >> return RETRecreate
|
||||
where
|
||||
initPgSourceCatalog = do
|
||||
() <- Q.multiQE defaultTxErrorHandler $(makeRelativeToProject "src-rsr/init_pg_source.sql" >>= Q.sqlFromFile)
|
||||
|
@ -218,6 +218,8 @@ instance (Cacheable a, Cacheable b, Cacheable c) => Cacheable (a, b, c)
|
||||
instance (Cacheable a, Cacheable b, Cacheable c, Cacheable d) => Cacheable (a, b, c, d)
|
||||
instance (Cacheable a, Cacheable b, Cacheable c, Cacheable d, Cacheable e) => Cacheable (a, b, c, d, e)
|
||||
instance (Cacheable a, Cacheable b, Cacheable c, Cacheable d, Cacheable e, Cacheable f) => Cacheable (a, b, c, d, e, f)
|
||||
instance (Cacheable a, Cacheable b, Cacheable c, Cacheable d, Cacheable e, Cacheable f, Cacheable g) => Cacheable (a, b, c, d, e, f, g)
|
||||
|
||||
|
||||
instance Cacheable Bool
|
||||
instance Cacheable Void
|
||||
|
@ -311,10 +311,10 @@ buildSchemaCacheRule env = proc (metadata, invalidationKeys) -> do
|
||||
, HasServerConfigCtx m
|
||||
, MonadError QErr m
|
||||
)
|
||||
=> (Int, SourceConfig b) `arr` ()
|
||||
=> (Int, SourceConfig b) `arr` RecreateEventTriggers
|
||||
initCatalogIfNeeded = Inc.cache proc (numEventTriggers, sc) -> do
|
||||
arrM id -< do
|
||||
when (numEventTriggers > 0) do
|
||||
if (numEventTriggers > 0) then do
|
||||
case backendTag @b of
|
||||
Tag.PostgresVanillaTag -> do
|
||||
migrationTime <- liftIO getCurrentTime
|
||||
@ -331,12 +331,18 @@ buildSchemaCacheRule env = proc (metadata, invalidationKeys) -> do
|
||||
-- migrating the catalog on error and in the retry `initCatalogForSource`
|
||||
-- will see that the catalog is already migrated, so it won't attempt the
|
||||
-- migration again
|
||||
liftEither =<< Retry.retrying
|
||||
liftEither =<<
|
||||
Retry.retrying
|
||||
(Retry.constantDelay (fromIntegral $ diffTimeToMicroSeconds $ seconds $ Seconds 10)
|
||||
<> Retry.limitRetries 3)
|
||||
(const $ return . isLeft)
|
||||
(const initCatalogAction)
|
||||
_ -> pure ()
|
||||
-- TODO: When event triggers are supported on new databases,
|
||||
-- the initialization of the source catalog should also return
|
||||
-- if the event triggers are to be re-created or not, essentially
|
||||
-- replacing the `RETDoNothing` below
|
||||
_ -> pure RETDoNothing
|
||||
else pure RETDoNothing
|
||||
|
||||
buildSource
|
||||
:: forall b arr m
|
||||
@ -363,7 +369,7 @@ buildSchemaCacheRule env = proc (metadata, invalidationKeys) -> do
|
||||
metadataInvalidationKey = Inc.selectD #_ikMetadata invalidationKeys
|
||||
numEventTriggers = sum $ map (length . snd) eventTriggers
|
||||
|
||||
initCatalogIfNeeded @b -< (numEventTriggers, sourceConfig)
|
||||
recreateEventTriggers <- initCatalogIfNeeded @b -< (numEventTriggers, sourceConfig)
|
||||
|
||||
-- tables
|
||||
tableRawInfos <- buildTableCache -< ( source, sourceConfig, dbTables
|
||||
@ -386,7 +392,7 @@ buildSchemaCacheRule env = proc (metadata, invalidationKeys) -> do
|
||||
permissionInfos <-
|
||||
buildTablePermissions
|
||||
-< (Proxy :: Proxy b, source, tableCoreInfosDep, tableFields, permissionInputs, inheritedRoles)
|
||||
eventTriggerInfos <- buildTableEventTriggers -< (source, sourceConfig, tableCoreInfo, eventTriggerConfs, metadataInvalidationKey)
|
||||
eventTriggerInfos <- buildTableEventTriggers -< (source, sourceConfig, tableCoreInfo, eventTriggerConfs, metadataInvalidationKey, recreateEventTriggers)
|
||||
returnA -< TableInfo tableCoreInfo permissionInfos eventTriggerInfos
|
||||
)
|
||||
|) (tableCoreInfos `alignTableMap` mapFromL _tpiTable permissions `alignTableMap` mapFromL fst eventTriggers)
|
||||
@ -621,9 +627,9 @@ buildSchemaCacheRule env = proc (metadata, invalidationKeys) -> do
|
||||
mkEventTriggerMetadataObject
|
||||
:: forall b a c
|
||||
. Backend b
|
||||
=> (a, SourceName, c, TableName b, EventTriggerConf)
|
||||
=> (a, SourceName, c, TableName b, RecreateEventTriggers, EventTriggerConf)
|
||||
-> MetadataObject
|
||||
mkEventTriggerMetadataObject (_, source, _, table, eventTriggerConf) =
|
||||
mkEventTriggerMetadataObject (_, source, _, table, _, eventTriggerConf) =
|
||||
let objectId = MOSourceObjId source
|
||||
$ AB.mkAnyBackend
|
||||
$ SMOTableObj @b table
|
||||
@ -695,14 +701,15 @@ buildSchemaCacheRule env = proc (metadata, invalidationKeys) -> do
|
||||
, MonadReader BuildReason m, HasServerConfigCtx m, BackendMetadata b)
|
||||
=> ( SourceName, SourceConfig b, TableCoreInfo b
|
||||
, [EventTriggerConf], Inc.Dependency Inc.InvalidationKey
|
||||
, RecreateEventTriggers
|
||||
) `arr` EventTriggerInfoMap
|
||||
buildTableEventTriggers = proc (source, sourceConfig, tableInfo, eventTriggerConfs, metadataInvalidationKey) ->
|
||||
buildInfoMap (etcName . (^. _5)) (mkEventTriggerMetadataObject @b) buildEventTrigger
|
||||
-< (tableInfo, map (metadataInvalidationKey, source, sourceConfig, _tciName tableInfo,) eventTriggerConfs)
|
||||
buildTableEventTriggers = proc (source, sourceConfig, tableInfo, eventTriggerConfs, metadataInvalidationKey, recreateEventTriggers) ->
|
||||
buildInfoMap (etcName . (^. _6)) (mkEventTriggerMetadataObject @b) buildEventTrigger
|
||||
-< (tableInfo, map (metadataInvalidationKey, source, sourceConfig, _tciName tableInfo, recreateEventTriggers, ) eventTriggerConfs)
|
||||
where
|
||||
buildEventTrigger = proc (tableInfo, (metadataInvalidationKey, source, sourceConfig, table, eventTriggerConf)) -> do
|
||||
buildEventTrigger = proc (tableInfo, (metadataInvalidationKey, source, sourceConfig, table, recreateEventTriggers, eventTriggerConf)) -> do
|
||||
let triggerName = etcName eventTriggerConf
|
||||
metadataObject = mkEventTriggerMetadataObject @b (metadataInvalidationKey, source, sourceConfig, table, eventTriggerConf)
|
||||
metadataObject = mkEventTriggerMetadataObject @b (metadataInvalidationKey, source, sourceConfig, table, recreateEventTriggers, eventTriggerConf)
|
||||
schemaObjectId = SOSourceObj source
|
||||
$ AB.mkAnyBackend
|
||||
$ SOITableObj @b table
|
||||
@ -712,14 +719,14 @@ buildSchemaCacheRule env = proc (metadata, invalidationKeys) -> do
|
||||
(| modifyErrA (do
|
||||
(info, dependencies) <- bindErrorA -< buildEventTriggerInfo @b env source table eventTriggerConf
|
||||
let tableColumns = M.mapMaybe (^? _FIColumn) (_tciFieldInfoMap tableInfo)
|
||||
recreateTriggerIfNeeded -< (metadataInvalidationKey, table, M.elems tableColumns, triggerName, etcDefinition eventTriggerConf, sourceConfig)
|
||||
recreateTriggerIfNeeded -< (metadataInvalidationKey, table, M.elems tableColumns, triggerName, etcDefinition eventTriggerConf, sourceConfig, recreateEventTriggers)
|
||||
recordDependencies -< (metadataObject, schemaObjectId, dependencies)
|
||||
returnA -< info)
|
||||
|) (addTableContext @b table . addTriggerContext))
|
||||
|) metadataObject
|
||||
|
||||
recreateTriggerIfNeeded = Inc.cache proc (metadataInvalidationKey, tableName, tableColumns
|
||||
, triggerName, triggerDefinition, sourceConfig) -> do
|
||||
, triggerName, triggerDefinition, sourceConfig, recreateEventTriggers) -> do
|
||||
-- We want to make sure we re-create event triggers in postgres database on
|
||||
-- `reload_metadata` metadata query request
|
||||
Inc.dependOn -< metadataInvalidationKey
|
||||
@ -727,7 +734,8 @@ buildSchemaCacheRule env = proc (metadata, invalidationKeys) -> do
|
||||
buildReason <- ask
|
||||
serverConfigCtx <- askServerConfigCtx
|
||||
-- we don't modify the existing event trigger definitions in the maintenance mode
|
||||
when (buildReason == CatalogUpdate && _sccMaintenanceMode serverConfigCtx == MaintenanceModeDisabled)
|
||||
when ((buildReason == CatalogUpdate || recreateEventTriggers == RETRecreate)
|
||||
&& _sccMaintenanceMode serverConfigCtx == MaintenanceModeDisabled)
|
||||
$ liftEitherM
|
||||
$ createTableEventTrigger
|
||||
serverConfigCtx
|
||||
|
@ -22,6 +22,8 @@ module Hasura.RQL.Types.EventTrigger
|
||||
|
||||
, defaultRetryConf
|
||||
, defaultTimeoutSeconds
|
||||
|
||||
, RecreateEventTriggers (..)
|
||||
) where
|
||||
|
||||
import Hasura.Prelude
|
||||
@ -289,3 +291,9 @@ instance Backend b => FromJSON (InvokeEventTriggerQuery b) where
|
||||
|
||||
instance Backend b => ToJSON (InvokeEventTriggerQuery b) where
|
||||
toJSON = genericToJSON hasuraJSON{omitNothingFields=True}
|
||||
|
||||
data RecreateEventTriggers
|
||||
= RETRecreate
|
||||
| RETDoNothing
|
||||
deriving (Show, Eq, Generic)
|
||||
instance Cacheable RecreateEventTriggers
|
||||
|
@ -131,7 +131,7 @@ data BuildReason
|
||||
-- updated the catalog. Since that instance already updated table event triggers in @hdb_catalog@,
|
||||
-- this build should be read-only.
|
||||
| CatalogSync
|
||||
deriving (Eq)
|
||||
deriving (Eq, Show)
|
||||
|
||||
data CacheInvalidations = CacheInvalidations
|
||||
{ ciMetadata :: !Bool
|
||||
|
Loading…
Reference in New Issue
Block a user