I'd like to have a one-to-one correspondence between the text I send to the Textlint worker and the lint result I receive from the Textlint worker.
However, the order I received results from the Textlint worker can differ from the one I posted texts to the worker probably because kernel.lintText is async. Ref:
|
return kernel.lintText(data.text, { |
|
rules: rules, |
|
filterRules: config.filterRules, |
|
plugins: config.plugins, |
|
filePath: "/path/to/README" + data.ext, |
|
ext: data.ext, |
|
}).then(result => { |
|
return self.postMessage({ |
|
command: "lint:result", |
|
result |
|
}); |
|
}); |
So relying on message reception order can cause a race condition. Pseudocode:
worker.addEventListener("message", (event) => {
// lint result of text#2 comes first
// lint result of text#1 comes next
})
worker.postMessage({
command: "lint",
text: "text#1 very long text that takes a long time to lint",
ext: ".txt"
})
worker.postMessage({
command: "lint",
text: "text#2 short text; lint finishes quickly",
ext: ".txt"
})
More higher-level example:
|
const lintText: LintEngineAPI["lintText"] = async ({ text }: { text: string }): Promise<TextlintResult[]> => { |
|
updateStatus("linting..."); |
|
return new Promise((resolve, _reject) => { |
|
worker.addEventListener( |
|
"message", |
|
function (event) { |
|
const data: TextlintWorkerCommandResponse = event.data; |
|
if (data.command === "lint:result") { |
|
resolve([data.result]); |
|
} |
|
updateStatus("linted"); |
|
}, |
|
{ |
|
once: true |
|
} |
|
); |
|
return worker.postMessage({ |
|
command: "lint", |
|
text, |
|
ext: ext |
|
} as TextlintWorkerCommandLint); |
|
}); |
|
}; |
const texts = ["text#1 very long text that takes a long time to lint", "text#2 short text; lint finishes quickly"]
const results = await Promise.all(texts => lintText({ text }))
// [<lint result of text#2>, <lint result of text#2>]
// lint result of text#1 goes away
Some Web Worker libraries use IDs in messages. I think it can be one of the ideas to solve this problem.
For example, comlink:
https://github.com/GoogleChromeLabs/comlink/blob/dffe9050f63b1b39f30213adeb1dd4b9ed7d2594/src/comlink.ts#L596-L615
For another example, minlink:
https://github.com/mizchi/minlink/blob/98f0eed1b1fc00a51709e07c6fe3e18232cdfaad/src/shared.ts#L52-L61
I'd like to have a one-to-one correspondence between the text I send to the Textlint worker and the lint result I receive from the Textlint worker.
However, the order I received results from the Textlint worker can differ from the one I posted texts to the worker probably because
kernel.lintTextis async. Ref:editor/packages/@textlint/script-compiler/src/CodeGenerator/worker-codegen.ts
Lines 125 to 136 in b32d016
So relying on message reception order can cause a race condition. Pseudocode:
More higher-level example:
editor/packages/textchecker-element/index.ts
Lines 41 to 63 in b32d016
Some Web Worker libraries use IDs in messages. I think it can be one of the ideas to solve this problem.
For example, comlink:
https://github.com/GoogleChromeLabs/comlink/blob/dffe9050f63b1b39f30213adeb1dd4b9ed7d2594/src/comlink.ts#L596-L615
For another example, minlink:
https://github.com/mizchi/minlink/blob/98f0eed1b1fc00a51709e07c6fe3e18232cdfaad/src/shared.ts#L52-L61