Giter Site home page Giter Site logo

issues's People

Contributors

benjie avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar

issues's Issues

Unable to enable pro plugin using docker image

I'm encountering an error when running the server using the docker image with the pro plugin enabled (it runs fine using the CLI)

Minimal docker example:

docker run -it --entrypoint ash --network="host" graphile/postgraphile:v4.6.0
#  === > (inside container)
yarn add @graphile/pro
export GRAPHILE_LICENSE=<GRAPHILE_LICENSE>
./cli.js --plugins @graphile/pro -c <CONNECTION_URL>

Any request to the server (including graphiql introspection) then yields a version of this error message:

Error: Cannot use GraphQLScalarType "Boolean" from another module or realm.

Ensure that there is only one instance of "graphql" in the node_modules directory. If different versions of "graphql" are the dependencies of other relied on modules, use "resolutions" to ensure only one version is installed.

https://yarnpkg.com/en/docs/selective-version-resolutions

Duplicate "graphql" modules cannot be used at the same time since different versions may have different capabilities and behavior. The data from one version used in the function from another could produce confusing and spurious results.

Originally posted on discord: https://discordapp.com/channels/489127045289476126/697954986461495346/732601497334054913

When inside of a resolver for a subscription, allow `selectGraphQLResultFromTable` to use the read only connection string

Feature description

When using subscriptions through GraphQL, you usually want to read from the main DB instance so you can get the freshest data available. However as an application scales this can put significant stress on the main DB.

Currently, PostGraphile allows you to provide a readOnlyConnection parameter that will send all query requests to it which is just fantastic! If the underlying query in a subscription could be also directed towards a read replica that would really help scale this out for larger applications.

I was thinking something along these lines:

  • Before running the subscription resolver, we can wait until select pg_last_xact_replay_timestamp(); returns a timestamp that is >= when the subscription triggered.
  • We'll use some sort of backoff for getting pg_last_xact_replay_timestamp (maybe exponential backoff?)
  • If we've waited over some sort of threshold that the user has set, we'll stop querying the RR and just grab the data from the main DB

Motivating example

Currently in prod, we have clients that are being streamed updated data from the API via subscriptions. As the number of the clients grows more reads are coming from the main DB than the RR which is causing significant performance issues.

Supporting development

I [tick all that apply]:

  • am interested in building this feature myself
  • am interested in collaborating on building this feature
  • am willing to help testing this feature before it's released
  • am willing to write a test-driven test suite for this feature (before it exists)
  • am a Graphile sponsor ❤️
  • have an active support or consultancy contract with Graphile

TS definitions for `@graphile/supporter`

I'm submitting a ...

  • bug report
  • feature request
  • question

It would be nice if the @graphile/supporter plugin shipped with TypeScript definitions, including a module augmentation on PostGraphileOptions to include Pro plugin options.

I think the declaration file would need to look something like this:

// index.d.ts

import { PostGraphilePlugin } from 'postgraphile';

declare const plugin: PostGraphilePlugin;
export default plugin;

declare module 'postgraphile' {
  export interface PostGraphileOptions {
    simpleSubscriptions?: boolean;
    readOnlyConnection?: boolean;
    defaultPaginationLimit?: number;
    graphqlDepthLimit?: number;
    graphqlCostLimit?: number;
    exposeGraphQLCost?: boolean;
  }
}

Graphile Pro: overrideOptionsForRequest defaultPaginationCap is not taken into account

Summary

defaultPaginationCap in overrideOptionsForRequest is not taken into account.

Steps to reproduce

I use this config of Graphile Pro:

postgraphile( dbUrl, schemaName, {
  defaultPaginationCap: -1,
  graphqlDepthLimit: -1,
  graphqlCostLimit: -1,
  exposeGraphQLCost: false,
  overrideOptionsForRequest(req) {
    return {
      defaultPaginationCap: 2,
      graphqlDepthLimit: 2, 
      graphqlCostLimit: 10000,
      exposeGraphQLCost: false
    };
  }
});

Expected results

  • I run a query with a cost > 10000 => I get an error saying it is above the allow limit ✅
  • I run a query with a depth > 2 => I get an error saying it is above the allow limit ✅
  • I run a query with no pagination => I get an error saying it is above the allow limit ✅
  • I run a query with first > 2 => I get an error saying it is above the allow limit ✅

Actual results

  • I run a query with a cost > 10000 => I get an error saying it is above the allow limit ✅
  • I run a query with a depth > 2 => I get an error saying it is above the allow limit ✅
  • I run a query with no pagination => Graphile let it pass while it shouldn't 🔴
  • I run a query with first > 2 => Graphile let it pass while it shouldn't 🔴

Additional context

More generally, the defaultPaginationCap returned by overrideOptionsForRequest is never taken into account. But the defaultPaginationCap from the config is well-enforced correctly.

We use quite a lot of plugins, but I don't see anything that would interfere with that. Especially knowing that defaultPaginationCap from config is well-enforced.

Using @graphile/[email protected] and [email protected] and [email protected]

Possible Solution

No idea since the plugin is not open source, and the minified code is not so easy to debug 😬

peerDependency on postgraphile missing in @graphile/pro

Summary

v1.0.0, does not declare postgraphile as a peerDependency in package.json, but it does import postgraphile at some point.

Importing a package that is not declared as a dep or peerDeep is not good, and yarn v2 is especially strict about that.

I had to use the workaround of adding these lines to my .yarnrc/yml

packageExtensions:
  "@graphile/pro@*":
    peerDependencies:
      postgraphile: "*"

Easy fix is to just add postgraphile as a peerDep in package json

Steps to reproduce

Use yarn v2 to install a server with postgraphile + @graphile/pro

Expected results

Works

Actual results

Yarn complains that @graphile/pro tries to import postgraphile without defining it in dependencies

Additional context

Possible Solution

Add this to package.json of @graphile/pro

    "peerDependencies": {
      "postgraphile": "*"
     }

Subscriptions relatedNode return null

I'm using Simple Subscriptions feature. If i set pgStrictFunctions is true, relatedNode return null. What should I do to use both of these features?

graphileBuildOptions: {
  pgStrictFunctions: true,
}
{
  "data": {
    "listen": {
      "relatedNodeId": "WyJwZW9wbGUiLDJd",
      "relatedNode": null
    }
  }
}

Introduce smart comments to allow hinting at the cost of an unlimited query of a table

If we could put a comment on a table or a foreign key constraint that would hint to the cost calculator what estimate it should use as the number of rows to be returned when a limit isn't specified in the query, it would allow the schema developer to provide a more streamlined experience to their users.

Having the ability to force users to specify a limit on very big tables works great, however, if you know the table is small and it won't return a lot of rows, then forcing the user to still specify a limit makes for a slightly clunkier experience for them. If we don't force them, then the calculated cost for the query is 1000 which is likely too high since we didn't force limits since we know there aren't that many rows to be returned.

At a minimum level, having the following comment would help:

maxRowEstimate -- Tells the calculator how many rows the dev expects would be returned if the user did not specify a limit. Can be put on a table, or on a foreign key constraint. If the relation is being hit via a link in the graph, the constraint value would take precedence, and if it isn't specified, fall back to the table value.

I imagine we could probably get fancier and try to tap into the pg stats, but while that would be fun, it would probably be a lot more complicated to figure out.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.