0

I created super simple application using nexus graphql framework.

First step like this:

https://www.nexusjs.org/#/tutorial/chapter-1-setup-and-first-query

I api/app.ts i typed code:

const uid = require('uid')

let i = 0;

const sleep = async (ms: number) => {
    return new Promise((resolve, reject) => {
        setTimeout(resolve, ms)
    })
}

const recurrenceFunction = async (id:string): Promise<void> => {
    i++;
    console.log(id, i);
    await sleep(2000);
    return recurrenceFunction(id)
}

const startQueue = () => {
    const id:string = uid();
    return recurrenceFunction(id)
}

(async () => {
    return startQueue()
})()

Only dependency is uid that generates unique keys.

When I run it with ts-node I can see:

enter image description here

So we can see:

  1. Once queue started.
  2. There is single queue.
  3. It works as it should work.

But when I run this code with nexus by command nexus dev I have seen:

enter image description here

So:

  1. Two queues started.
  2. They are running at the same time.
  3. They have independently created variables i.

Questions:

  • Is anyone meet with this problem?
  • How should I change my code to get single queue like in ts-node?
  • Or maybe it is bug of nexus?

Update:

I checked that this problem exists for verions >= 0.21.1-next.2

In 0.21.1-next.1 application runs single time.

Steps to reproduce:

nexus dev
npm i nexus@0.21.1-next.1
nexus dev
npm i nexus@0.21.1-next.2

there is commit that introduced this behavior:

https://github.com/graphql-nexus/nexus/commit/ce1d45359e33af81169b7ebdc7bee6718fe313a8

There is variables like onMainThread and REFLECTION_ENV_VAR but without references to documentation. I can't understand what this code is doing?

This probably will be documented in future in this place:

https://www.nexusjs.org/#/architecture?id=build-flow

but now there is:

enter image description here

Update 2

I found woraround:

const xid = uid();
let limit=10;
const onApplicationStart = async (cb: () => any):Promise<any> => {
    console.log("can i start?", xid, limit, app.private.state.running);
    if(app.private.state.running) {
        await cb()
        return;
    }
    limit--;
    if(limit <= 0) return ;
    await sleep(100);
    return onApplicationStart(cb);
}

(async () => {

    return onApplicationStart(async () => {
        return startQueue()
    })

})()

but this is rather temporary hack than solution. Full example:

https://github.com/graphql-nexus/nexus/discussions/983

Daniel
  • 7,684
  • 7
  • 52
  • 76
  • This should also have the tags: nexus, nexus-plugin-prisma – Jason Kuhrt Jun 07 '20 at 10:40
  • Tag "nexus" is used in other context (Repository Manager for Maven) stackoverflow.com/questions/tagged/nexus. We can propose new tag: "graphql-nexus" or "nexus-framework" to add them to stack overflow. – Daniel Jun 07 '20 at 12:06

1 Answers1

1

Eager module code relying on side-effects is not supported by Nexus.

See:

For a workaround for now wrap your code like this:

// app.ts
if (!process.env.NEXUS_REFLECTION) {
  yourHeavyAsyncCode()
}

Reference https://github.com/graphql-nexus/nexus/issues/732#issuecomment-626586244

Jason Kuhrt
  • 736
  • 1
  • 4
  • 12