Code Monkey home page Code Monkey logo

Comments (6)

benjie avatar benjie commented on September 23, 2024

Both NOTIFY and the unlogged table approach have the issue that messages are "rolled back" if a transaction is rolled back:

NOTIFY interacts with SQL transactions in some important ways. Firstly, if a NOTIFY is executed inside a transaction, the notify events are not delivered until and unless the transaction is committed. This is appropriate, since if the transaction is aborted, all the commands within it have had no effect, including NOTIFY.
-- https://www.postgresql.org/docs/current/sql-notify.html

For informational messages, this means if an error occurs the user can only see the error and not the details leading up to the error. This may or may not be acceptable, but it's certainly a trade-off.

Regarding the RAISE NOTICE (or even RAISE DEBUG) option, things are a little more interesting:

Whether messages of a particular priority are reported to the client, written to the server log, or both is controlled by the log_min_messages and client_min_messages configuration variables. See Chapter 19 for more information.
-- https://www.postgresql.org/docs/current/plpgsql-errors-and-messages.html

So we can log different things to the server logs vs to the client. That means we could use a particularly verbose level like DEBUG, LOG, INFO or NOTICE:

Allowed levels are DEBUG, LOG, INFO, NOTICE, WARNING, and EXCEPTION, with EXCEPTION being the default.

with a particular error code like GOPHK (Graphile OPeration HooKs, though if you try and read it it sounds a little different... Maybe we should choose a better abbreviation). We can then capture these notices, interpret them in a particular way (e.g. JSON) and add to the messages system.

I think the unlogged table route should be avoided, it doesn't really have any advantages over LISTEN/NOTIFY, but it does have many disadvantages.


Irrespective of how we do this, I don't think it should be a goal for the messages raised by these "ambient" functions to be retrievable by other SQL code that can make decisions based on it. We could support basic deduplication, perhaps, but if something requires the current operation to stop and it cannot be done in an explicit "before" check then it should raise an exception.


Shall ponder more.

from operation-hooks.

demianuco avatar demianuco commented on September 23, 2024

Agreed with all of the above. Ponder away, as I'm sure that what you will come back with will be good. I also have a feeling that it will be used a lot.

from operation-hooks.

benjie avatar benjie commented on September 23, 2024

From chat with @demianuco, this pseudo-code is the kind of shape I'd expect to apply to a single field. Once someone gets this working and padded out and checked for various issues (like synchronisation issues?) we could look at adding it more generically to this plugin

const { makeWrapResolversPlugin, makeExtendSchemaPlugin, makePluginByCombiningPlugins, gql } = require('graphile-utils');

const WrapPlugin = makeWrapResolversPlugin({
  Mutation: {
    myMutation(resolver, parent, args, context, info) {
      const { pgClient } = context;
      const notices = [];
      const push = msg => notices.push(msg);
      pgClient.on('notice', push);
      try {
        const result = await resolver();
        return {
          ...result,
          notices,
        };
      } finally {
        pgClient.removeListener('notice', push);
      }
    }
  }
});

const ExtendPlugin = makeExtendSchemaPlugin({
  typeDefs: gql`
    extend type MyMutationPayload {
      messages: SOMETHING_HERE
    }
  `,
  resolvers: {
    MyMutationPayload: {
      messages(myMutationResult, args, context, info) {
        const { notices } = myMutationResult; // < Extracted from the return result of makeWrapResolvers above
        return someMangledVersionOf(notices);
      }
    }
  }
};

module.exports = makePluginByCombiningPlugins([WrapPlugin, ExtendPlugin]);

from operation-hooks.

benjie avatar benjie commented on September 23, 2024

I read a bit of the PostgreSQL docs, and scanned through the node-postgres code, and I believe that this is reliable and not vulnerable to race conditions. I sponsor @brianc the node-postgres maintainer so I've reached out to him to validate my assumptions but I think we can go ahead with the NOTICE route 🎉.

from operation-hooks.

benjie avatar benjie commented on September 23, 2024

Brian confirmed my suspicions 👍

from operation-hooks.

benjie avatar benjie commented on September 23, 2024

First punt at this implemented in #16; would love some eyes on it.

from operation-hooks.

Related Issues (11)

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.