Skip to content

Commit

Permalink
server: pass a partially applied function instead of passing `AppStat…
Browse files Browse the repository at this point in the history
…eRef` to http handlers

PR-URL: hasura/graphql-engine-mono#8464
GitOrigin-RevId: b9dff36d2c560a093a6aff669315fe4fbc18b3f6
  • Loading branch information
ecthiender authored and hasura-bot committed Mar 23, 2023
1 parent bc75136 commit 14fcaaf
Showing 1 changed file with 17 additions and 29 deletions.
46 changes: 17 additions & 29 deletions server/src-lib/Hasura/Server/App.hs
Original file line number Diff line number Diff line change
Expand Up @@ -434,16 +434,6 @@ mkSpockAction appStateRef qErrEncoder qErrModifier apiHandler = do
mapM_ setHeader allRespHeaders
Spock.lazyBytes compressedResp

{- Note [Explicitly passing AppStateRef]
~~~~~~~~~~~~~~~~~~~~~~~
The AppStateRef is passed explicitly to `v1QueryHandler` and `v1MetadataHandler`
functions, so that they can update the schema cache in the ref.
They don't use it to read the latest AppContext or SchemaCache.
The AppContext or SchemaCache is read from the HandlerCtx.
This is to avoid any race conditions that can occur by reading AppContext/SchemaCache
one after the other.
-}

v1QueryHandler ::
( MonadIO m,
MonadError QErr m,
Expand All @@ -461,13 +451,12 @@ v1QueryHandler ::
UserInfoM m,
HasServerConfigCtx m
) =>
AppStateRef impl ->
(m (EncJSON, RebuildableSchemaCache) -> m EncJSON) ->
RQLQuery ->
m (HttpResponse EncJSON)
v1QueryHandler appStateRef query = do
v1QueryHandler schemaCacheRefUpdater query = do
(liftEitherM . authorizeV1QueryApi query) =<< ask
logger <- _lsLogger . appEnvLoggers <$> askAppEnv
res <- bool (fst <$> action) (withSchemaCacheUpdate appStateRef logger Nothing action) $ queryModifiesSchemaCache query
res <- bool (fst <$> action) (schemaCacheRefUpdater action) $ queryModifiesSchemaCache query
return $ HttpResponse res []
where
action = do
Expand Down Expand Up @@ -495,20 +484,16 @@ v1MetadataHandler ::
UserInfoM m,
HasServerConfigCtx m
) =>
AppStateRef impl ->
(m (EncJSON, RebuildableSchemaCache) -> m EncJSON) ->
RQLMetadata ->
m (HttpResponse EncJSON)
v1MetadataHandler appStateRef query = Tracing.newSpan "Metadata" $ do
v1MetadataHandler schemaCacheRefUpdater query = Tracing.newSpan "Metadata" $ do
(liftEitherM . authorizeV1MetadataApi query) =<< ask
logger <- _lsLogger . appEnvLoggers <$> askAppEnv
appContext <- asks hcAppContext
schemaCache <- asks hcSchemaCache
r <-
withSchemaCacheUpdate
appStateRef
logger
Nothing
$ runMetadataQuery
schemaCacheRefUpdater $
runMetadataQuery
appContext
schemaCache
query
Expand All @@ -529,14 +514,13 @@ v2QueryHandler ::
UserInfoM m,
HasServerConfigCtx m
) =>
AppStateRef impl ->
(m (EncJSON, RebuildableSchemaCache) -> m EncJSON) ->
V2Q.RQLQuery ->
m (HttpResponse EncJSON)
v2QueryHandler appStateRef query = Tracing.newSpan "v2 Query" $ do
v2QueryHandler schemaCacheRefUpdater query = Tracing.newSpan "v2 Query" $ do
(liftEitherM . authorizeV2QueryApi query) =<< ask
logger <- _lsLogger . appEnvLoggers <$> askAppEnv
res <-
bool (fst <$> dbAction) (withSchemaCacheUpdate appStateRef logger Nothing dbAction) $
bool (fst <$> dbAction) (schemaCacheRefUpdater dbAction) $
V2Q.queryModifiesSchema query
return $ HttpResponse res []
where
Expand Down Expand Up @@ -922,23 +906,27 @@ httpApp setupHook appStateRef AppEnv {..} ekgStore = do
mkGetHandler $ customEndpointHandler (RestRequest wildcard method allParams)

when (isMetadataEnabled appCtx) $ do
-- Note: we create a schema cache updater function, to restrict the access
-- to 'AppStateRef' inside the request handlers
let schemaCacheUpdater = withSchemaCacheUpdate appStateRef logger Nothing

Spock.post "v1/graphql/explain" gqlExplainAction

Spock.post "v1alpha1/graphql/explain" gqlExplainAction

Spock.post "v1/query" $
spockAction encodeQErr id $ do
mkPostHandler $ fmap (emptyHttpLogGraphQLInfo,) <$> mkAPIRespHandler (v1QueryHandler appStateRef)
mkPostHandler $ fmap (emptyHttpLogGraphQLInfo,) <$> mkAPIRespHandler (v1QueryHandler schemaCacheUpdater)

Spock.post "v1/metadata" $
spockAction encodeQErr id $
mkPostHandler $
fmap (emptyHttpLogGraphQLInfo,) <$> mkAPIRespHandler (v1MetadataHandler appStateRef)
fmap (emptyHttpLogGraphQLInfo,) <$> mkAPIRespHandler (v1MetadataHandler schemaCacheUpdater)

Spock.post "v2/query" $
spockAction encodeQErr id $
mkPostHandler $
fmap (emptyHttpLogGraphQLInfo,) <$> mkAPIRespHandler (v2QueryHandler appStateRef)
fmap (emptyHttpLogGraphQLInfo,) <$> mkAPIRespHandler (v2QueryHandler schemaCacheUpdater)

when (isPGDumpEnabled appCtx) $
Spock.post "v1alpha1/pg_dump" $
Expand Down

0 comments on commit 14fcaaf

Please sign in to comment.