graphql-engine/server/src-lib/Hasura
Auke Booij 1007ea27ae server: refactor MonadSchema into MonadMemoize
Followup to hasura/graphql-engine-mono#4713.

The `memoizeOn` method, part of `MonadSchema`, originally had the following type:
```haskell
  memoizeOn
    :: (HasCallStack, Ord a, Typeable a, Typeable b, Typeable k)
    => TH.Name
    -> a
    -> m (Parser k n b)
    -> m (Parser k n b)
```
The reason for operating on `Parser`s specifically was that the `MonadSchema` effect would additionally initialize certain `Unique` values, which appear (nested in) the type of `Parser`.

hasura/graphql-engine-mono#518 changed the type of `memoizeOn`, to additionally allow memoizing `FieldParser`s. These also contained a `Unique` value, which was similarly initialized by the `MonadSchema` effect. The new type of `memoizeOn` was as follows:
```haskell
  memoizeOn
    :: forall p d a b
     . (HasCallStack, HasDefinition (p n b) d, Ord a, Typeable p, Typeable a, Typeable b)
    => TH.Name
    -> a
    -> m (p n b)
    -> m (p n b)
```

Note the type `p n b` of the value being memoized: by choosing `p` to be either `Parser k` or `FieldParser`, both can be memoized. Also note the new `HasDefinition (p n b) d` constraint, which provided a `Lens` for accessing the `Unique` value to be initialized.

A quick simplification is that the `HasCallStack` constraint has never been used by any code. This was realized in hasura/graphql-engine-mono#4713, by removing that constraint.

hasura/graphql-engine-mono#2980 removed the `Unique` value from our GraphQL-related types entirely, as their original purpose was never truly realized. One part of removing `Unique` consisted of dropping the `HasDefinition (p n b) d` constraint from `memoizeOn`.

What I didn't realize at the time was that this meant that the type of `memoizeOn` could be generalized and simplified much further. This PR finally implements that generalization. The new type is as follows:
```haskell
  memoizeOn ::
    forall a p.
    (Ord a, Typeable a, Typeable p) =>
    TH.Name ->
    a ->
    m p ->
    m p
```

This change has a couple of consequences.

1. While constructing the schema, we often output `Maybe (Parser ...)`, to model that the existence of certain pieces of GraphQL schema sometimes depends on the permissions that a certain role has. The previous versions of `memoizeOn` were not able to handle this, as the only thing they could memoize was fully-defined (if not yet fully-evaluated) `(Field)Parser`s. This much more general API _would_ allow memoizing `Maybe (Parser ...)`s. However, we probably have to be continue being cautious with this: if we blindly memoize all `Maybe (Parser ...)`s, the resulting code may never be able to decide whether the value is `Just` or `Nothing` - i.e. it never commits to the existence-or-not of a GraphQL schema fragment. This would manifest as a non-well-founded knot tying, and this would get reported as an error by the implementation of `memoizeOn`.

   tl;dr: This generalization _technically_ allows for memoizing `Maybe` values, but we probably still want to avoid doing so.

   For this reason, the PR adds a specialized version of `memoizeOn` to `Hasura.GraphQL.Schema.Parser`.
2. There is no longer any need to connect the `MonadSchema` knot-tying effect with the `MonadParse` effect. In fact, after this PR, the `memoizeOn` method is completely GraphQL-agnostic, and so we implement hasura/graphql-engine-mono#4726, separating `memoizeOn` from `MonadParse` entirely - `memoizeOn` can be defined and implemented as a general Haskell typeclass method.

   Since `MonadSchema` has been made into a single-type-parameter type class, it has been renamed to something more general, namely `MonadMemoize`. Its only task is to memoize arbitrary `Typeable p` objects under a combined key consisting of a `TH.Name` and a `Typeable a`.

   Also for this reason, the new `MonadMemoize` has been moved to the more general `Control.Monad.Memoize`.
3. After this change, it's somewhat clearer what `memoizeOn` does: it memoizes an arbitrary value of a `Typeable` type. The only thing that needs to be understood in its implementation is how the manual blackholing works. There is no more semantic interaction with _any_ GraphQL code.

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/4725
Co-authored-by: Daniel Harvey <4729125+danieljharvey@users.noreply.github.com>
GitOrigin-RevId: 089fa2e82c2ce29da76850e994eabb1e261f9c92
2022-08-04 13:45:53 +00:00
..
Backends server: refactor MonadSchema into MonadMemoize 2022-08-04 13:45:53 +00:00
Base server: Move ErrorMessage to its own package. 2022-07-27 04:38:12 +00:00
Cache server, pro: actually reformat the code-base using ormolu 2021-09-23 22:57:37 +00:00
Eventing server/postgres: document and refactor IdentifierUniqueness and SQL.DML 2022-07-18 09:46:17 +00:00
GraphQL server: refactor MonadSchema into MonadMemoize 2022-08-04 13:45:53 +00:00
Incremental remove homebrew NESeq, use vendored 2022-07-19 08:42:28 +00:00
Metadata server: convert Metadata to DTO (smaller PR) 2022-08-01 12:50:00 +00:00
RQL server/console: add metadata API set_apollo_federation_config 2022-08-04 09:38:02 +00:00
Server server/console: add metadata API set_apollo_federation_config 2022-08-04 09:38:02 +00:00
SQL Rewrite OpenAPI 2022-06-30 12:57:09 +00:00
App.hs server: Add warning log for no admin secret 2022-07-27 11:47:32 +00:00
EncJSON.hs Fix JSON encoding issue (fix hasura/graphql-engine#7543 and hasura/graphql-engine#8200) 2022-04-05 19:11:30 +00:00
GC.hs server: add explicit export lists in OSS server and enforce with warning 2021-11-04 16:09:38 +00:00
HTTP.hs Add Data Connector agent request logging, improve error messages, and add tracing support [GDW-83] 2022-07-11 08:05:40 +00:00
Incremental.hs server, pro: actually reformat the code-base using ormolu 2021-09-23 22:57:37 +00:00
Logging.hs Add Data Connector agent request logging, improve error messages, and add tracing support [GDW-83] 2022-07-11 08:05:40 +00:00
Name.hs server: support for Apollo federation 2022-07-25 15:54:41 +00:00
Prelude.hs Use witherable, remove catMaybes/mapMaybe 2022-07-29 14:53:16 +00:00
QueryTags.hs server: support query tags for MSSQL data sources 2022-04-28 19:34:45 +00:00
Session.hs Weeding (2/?) 2022-06-09 16:40:49 +00:00
Tracing.hs Add Data Connector agent request logging, improve error messages, and add tracing support [GDW-83] 2022-07-11 08:05:40 +00:00