2023-01-23 16:35:48 +03:00
|
|
|
{-# LANGUAGE DeriveAnyClass #-}
|
|
|
|
|
|
|
|
-- | Feature Flags are /temporary/ toggles.
|
|
|
|
module Hasura.Server.Init.FeatureFlag
|
|
|
|
( FeatureFlag (..),
|
2023-03-22 13:46:54 +03:00
|
|
|
CheckFeatureFlag (..),
|
2023-01-26 12:39:49 +03:00
|
|
|
checkFeatureFlag,
|
2023-01-23 16:35:48 +03:00
|
|
|
Identifier (..),
|
|
|
|
FeatureFlags (..),
|
Remove `ServerConfigCtx`.
### Description
This PR removes `ServerConfigCtx` and `HasServerConfigCtx`. Instead, it favours different approaches:
- when the code was only using one field, it passes that field explicitly (usually `SQLGenCtx` or `CheckFeatureFlag`)
- when the code was using several fields, but in only one function, it inlines
- for the cache build, it introduces `CacheStaticConfig` and `CacheDynamicConfig`, which are subsets of `AppEnv` and `AppContext` respectively
The main goal of this is to help with the modularization of the engine: as `ServerConfigCtx` had fields whose types were imported from several unrelated parts of the engine, using it tied together parts of the engine that should not be aware of one another (such as tying together `Hasura.LogicalModel` and `Hasura.GraphQL.Schema`).
The bulk of this PR is a change to the cache build, as a follow up to #8509: instead of giving the entire `ServerConfigCtx` as a incremental rule argument, we only give the new `CacheDynamicConfig` struct, which has fewer fields. The other required fields, that were coming from the `AppEnv`, are now given via the `HasCacheStaticConfig` constraint, which is a "subset" of `HasAppEnv`.
(Some further work could include moving `StringifyNumbers` out of `GraphQL.Schema.Options`, given how it is used all across the codebase, including in `RQL.DML`.)
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/8513
GitOrigin-RevId: 818cbcd71494e3cd946b06adbb02ca328a8a298e
2023-04-04 18:59:58 +03:00
|
|
|
HasFeatureFlagChecker (..),
|
2023-01-23 16:35:48 +03:00
|
|
|
featureFlags,
|
2023-04-13 19:10:38 +03:00
|
|
|
nativeQueryInterface,
|
2023-05-04 15:43:59 +03:00
|
|
|
storedProceduresFlag,
|
2023-01-23 16:35:48 +03:00
|
|
|
)
|
|
|
|
where
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
import Data.Aeson (FromJSON, ToJSON)
|
2023-01-26 12:39:49 +03:00
|
|
|
import Data.Environment qualified as Env
|
2023-01-23 16:35:48 +03:00
|
|
|
import Data.HashMap.Strict qualified as HashMap
|
|
|
|
import Hasura.Prelude
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
newtype Identifier = Identifier {getIdentifier :: Text}
|
|
|
|
deriving stock (Generic)
|
|
|
|
deriving newtype (Eq, FromJSON, ToJSON)
|
|
|
|
deriving anyclass (Hashable)
|
|
|
|
|
|
|
|
data FeatureFlag = FeatureFlag
|
|
|
|
{ ffIdentifier :: Identifier,
|
|
|
|
ffDefaultValue :: Bool,
|
2023-01-26 12:39:49 +03:00
|
|
|
ffDescription :: Text,
|
|
|
|
ffEnvVar :: String
|
2023-01-23 16:35:48 +03:00
|
|
|
}
|
|
|
|
deriving stock (Eq, Generic)
|
|
|
|
deriving anyclass (Hashable, FromJSON, ToJSON)
|
|
|
|
|
2023-01-26 12:39:49 +03:00
|
|
|
-- | In OSS we look for a environment variable or fall back to the default
|
|
|
|
-- value
|
|
|
|
checkFeatureFlag :: Env.Environment -> FeatureFlag -> IO Bool
|
|
|
|
checkFeatureFlag env (FeatureFlag {ffEnvVar = envVar, ffDefaultValue = defaultValue}) =
|
|
|
|
case Env.lookupEnv env envVar of
|
|
|
|
Just found -> pure $ fromMaybe defaultValue (readMaybe found)
|
|
|
|
Nothing -> pure $ defaultValue
|
2023-01-23 16:35:48 +03:00
|
|
|
|
2023-03-22 13:46:54 +03:00
|
|
|
newtype CheckFeatureFlag = CheckFeatureFlag {runCheckFeatureFlag :: FeatureFlag -> IO Bool}
|
|
|
|
|
2023-01-23 16:35:48 +03:00
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
newtype FeatureFlags = FeatureFlags {getFeatureFlags :: HashMap Text FeatureFlag}
|
|
|
|
|
|
|
|
featureFlags :: FeatureFlags
|
|
|
|
featureFlags =
|
|
|
|
FeatureFlags $
|
|
|
|
HashMap.fromList
|
|
|
|
[ ("test-flag", testFlag),
|
2023-05-04 15:43:59 +03:00
|
|
|
("native-query-interface", nativeQueryInterface),
|
|
|
|
("stored-procedures", storedProceduresFlag)
|
2023-01-23 16:35:48 +03:00
|
|
|
]
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
Remove `ServerConfigCtx`.
### Description
This PR removes `ServerConfigCtx` and `HasServerConfigCtx`. Instead, it favours different approaches:
- when the code was only using one field, it passes that field explicitly (usually `SQLGenCtx` or `CheckFeatureFlag`)
- when the code was using several fields, but in only one function, it inlines
- for the cache build, it introduces `CacheStaticConfig` and `CacheDynamicConfig`, which are subsets of `AppEnv` and `AppContext` respectively
The main goal of this is to help with the modularization of the engine: as `ServerConfigCtx` had fields whose types were imported from several unrelated parts of the engine, using it tied together parts of the engine that should not be aware of one another (such as tying together `Hasura.LogicalModel` and `Hasura.GraphQL.Schema`).
The bulk of this PR is a change to the cache build, as a follow up to #8509: instead of giving the entire `ServerConfigCtx` as a incremental rule argument, we only give the new `CacheDynamicConfig` struct, which has fewer fields. The other required fields, that were coming from the `AppEnv`, are now given via the `HasCacheStaticConfig` constraint, which is a "subset" of `HasAppEnv`.
(Some further work could include moving `StringifyNumbers` out of `GraphQL.Schema.Options`, given how it is used all across the codebase, including in `RQL.DML`.)
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/8513
GitOrigin-RevId: 818cbcd71494e3cd946b06adbb02ca328a8a298e
2023-04-04 18:59:58 +03:00
|
|
|
class Monad m => HasFeatureFlagChecker m where
|
|
|
|
checkFlag :: FeatureFlag -> m Bool
|
|
|
|
|
|
|
|
instance HasFeatureFlagChecker m => HasFeatureFlagChecker (ReaderT r m) where
|
|
|
|
checkFlag = lift . checkFlag
|
|
|
|
|
|
|
|
instance HasFeatureFlagChecker m => HasFeatureFlagChecker (ExceptT e m) where
|
|
|
|
checkFlag = lift . checkFlag
|
|
|
|
|
|
|
|
instance HasFeatureFlagChecker m => HasFeatureFlagChecker (StateT s m) where
|
|
|
|
checkFlag = lift . checkFlag
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
2023-01-23 16:35:48 +03:00
|
|
|
testFlag :: FeatureFlag
|
|
|
|
testFlag =
|
|
|
|
FeatureFlag
|
|
|
|
{ ffIdentifier = Identifier "test-flag",
|
|
|
|
ffDefaultValue = False,
|
2023-01-26 12:39:49 +03:00
|
|
|
ffDescription = "Testing feature flag integration",
|
|
|
|
ffEnvVar = "HASURA_FF_TEST_FLAG"
|
2023-01-23 16:35:48 +03:00
|
|
|
}
|
|
|
|
|
2023-04-13 19:10:38 +03:00
|
|
|
nativeQueryInterface :: FeatureFlag
|
|
|
|
nativeQueryInterface =
|
2023-01-23 16:35:48 +03:00
|
|
|
FeatureFlag
|
|
|
|
{ ffIdentifier = Identifier "native-query-interface",
|
|
|
|
ffDefaultValue = False,
|
2023-01-26 12:39:49 +03:00
|
|
|
ffDescription = "Expose custom views, permissions and advanced SQL functionality via custom queries",
|
2023-04-13 19:10:38 +03:00
|
|
|
ffEnvVar = "HASURA_FF_NATIVE_QUERY_INTERFACE"
|
2023-01-23 16:35:48 +03:00
|
|
|
}
|
2023-05-04 15:43:59 +03:00
|
|
|
|
|
|
|
storedProceduresFlag :: FeatureFlag
|
|
|
|
storedProceduresFlag =
|
|
|
|
FeatureFlag
|
|
|
|
{ ffIdentifier = Identifier "stored-procedures",
|
|
|
|
ffDefaultValue = False,
|
|
|
|
ffDescription = "Expose stored procedures support",
|
|
|
|
ffEnvVar = "HASURA_FF_STORED_PROCEDURES"
|
|
|
|
}
|