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:
So we can see:
- Once queue started.
- There is single queue.
- It works as it should work.
But when I run this code with nexus
by command nexus dev
I have seen:
So:
- Two queues started.
- They are running at the same time.
- 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:
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: