Почему команда nexus dev запускает приложение дважды и как это исправить?
Я создал супер простое приложение, используя платформу nexus graphql.
Первый шаг такой:
https://www.nexusjs.org/#/tutorial/chapter-1-setup-and-first-query
я api/app.ts
я набрал код:
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()
})()
Только зависимость uid
который генерирует уникальные ключи.
Когда я запускаю его с помощью ts-node, я вижу:
Итак, мы видим:
- Как только очередь началась.
- Единая очередь.
- Работает так, как и должно работать.
Но когда я запускаю этот код с nexus
по команде nexus dev
Я видел:
Так:
- Начались две очереди.
- Они работают одновременно.
- Они независимо создали переменные
i
.
Вопросы:
- Кто-нибудь встречался с этой проблемой?
- Как мне изменить свой код, чтобы получить единую очередь, как в
ts-node
? - А может это ошибка
nexus
?
Обновить:
Я проверил, что эта проблема существует для версий>= 0.21.1-next.2
В 0.21.1-next.1
приложение запускается один раз.
Действия по воспроизведению:
nexus dev
npm i nexus@0.21.1-next.1
nexus dev
npm i nexus@0.21.1-next.2
есть фиксация, которая ввела это поведение:
https://github.com/graphql-nexus/nexus/commit/ce1d45359e33af81169b7ebdc7bee6718fe313a8
Есть такие переменные, как onMainThread
а также REFLECTION_ENV_VAR
но без ссылок на документацию. Я не могу понять, что делает этот код?
Это, вероятно, будет задокументировано в будущем в этом месте:
но сейчас есть:
Обновление 2
Я обнаружил, что вокруг:
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()
})
})()
но это скорее временный взлом, чем решение. Полный пример:
1 ответ
Код нетерпеливого модуля, основанный на побочных эффектах, не поддерживается Nexus.
Видеть:
- https://www.nexusjs.org/#/tutorial/chapter-2-writing-your-first-schema?id=reflection
- https://github.com/graphql-nexus/nexus/issues/758
Для временного решения оберните ваш код следующим образом:
// app.ts
if (!process.env.NEXUS_REFLECTION) {
yourHeavyAsyncCode()
}