Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] v5 PgNoticeMessagesPlugin, am I on the right track? #2259

Open
kzlar opened this issue Dec 1, 2024 · 1 comment
Open

[Question] v5 PgNoticeMessagesPlugin, am I on the right track? #2259

kzlar opened this issue Dec 1, 2024 · 1 comment

Comments

@kzlar
Copy link
Contributor

kzlar commented Dec 1, 2024

Hi Benjie,

On my v4 deployment I rely on the opertaions-hook plugin for several use-cases, one of them is the PgNoticeMessages.
My understanding is that this wasn't ported to v5 yet, so I figured I'd tackle at least the PgNoticeMessages part.
I followed https://github.com/graphile/operation-hooks/blob/main/src/PgNoticeMessagesPlugin.ts and here's what I have so far:

export const PgMessagesPlugin: GraphileConfig.Plugin = {
  name: 'PgMessagesPlugin',
  description: 'Extract postgres RAISE NOTICE messages',
  version: '0.0.1',

  grafast: {
    middleware: {
      execute(next, event) {
        const ctx = event.args.contextValue as {
          pgSettings: object
          withPgClient: (
            settings: object,
            cb: (args: { rawClient: Client }) => void
          ) => Promise<void>
        }
        const noticeCallback = (notice: NoticeMessage) => {
          console.debug(`PgMessagesPlugin notice: ${JSON.stringify(notice)}`)
        }
        return ctx
          .withPgClient(ctx.pgSettings, (args: { rawClient: Client }) => {
            assert(!('processNotice' in args.rawClient))
            args.rawClient['processNotice'] = noticeCallback
            args.rawClient.on('notice', noticeCallback)
          })
          .then(() => {
            return Promise.resolve(next()).then((v) => {
              ctx.withPgClient(
                ctx.pgSettings,
                (args: { rawClient: Client }) => {
                  args.rawClient.removeListener('notice', noticeCallback)
                  delete args.rawClient['processNotice']
                }
              )
              return v
            })
          })
      },
    },
  },
}

Apart for the type hackiness, it seems to work. But I wanted to double check before continuing down this path:

  1. Am I on the right track?
  2. Is there a better way to extract the type of withPgClient?
  3. My next step would be to extract the data, and I assume I should add it to event.args.contextValue, sounds right? That'll let me access the data further down the line.
  4. I'm assuming that this needs to be the very last plugin in my graphile.config to make sure any other plugin can read that context, correct?
  5. My other next step would be to create a plugin to extract the data from the context to the mutations. The most appropriate one would be makeExtendSchemaPlugin, correct?

P.S. if this all goes well I'd be happy to open source it, let me know if that would be best done as a PR to this repo.

@github-project-automation github-project-automation bot moved this to 🌳 Triage in V5.0.0 Dec 1, 2024
@benjie
Copy link
Member

benjie commented Dec 4, 2024

We don't have official support for this. If you want to hack it, you need to override withPgClient because each time it's called it might be passed a different client.

const ctx = event.args.contextValue as Graphile.Context;
const processNotice = e => void console.log(e);
const oldWithPgClient = ctx.withPgClient;
ctx.withPgClient = (settings, cb) => 
  oldWithPgClient(settings, (client) => {
    const { rawClient } = client;
    if (!rawClient) throw new error("This postgres adaptor is not supported - sorry!");
    rawClient.on('notice', processNotice);
    try {
      return await cb(client);
    } finally {
      rawClient.off('notice', processNotice);
    }
  });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: 🌳 Triage
Development

No branches or pull requests

2 participants