当尝试使用广播频道在主脚本和工作者之间进行通信时,我遇到了一些问题。我在主脚本中有以下代码:
spark2-submit --master yarn/local --class org.apache.kudu.spark.tools.ImportExportFiles <path of kudu jar>/kudu-spark2-tools_2.11-1.6.0.jar --operation=import --format=<parquet/avro/csv> --master-addrs=<kudu master host>:<port number> --path=<hdfs path for data> --table-name=impala::<table name>
和两个工人中的类似代码:
const channel = new BroadcastChannel('my_bus');
const worker = new Worker('worker.js');
const secondWorker = new Worker('second-worker.js');
channel.postMessage('1000');
问题是当主脚本发出的消息,工作者还没有加载时,所以他们跳过了消息。我很确定,因为如果我做这样的事情,它可以正常工作:
const bc = new BroadcastChannel('my_bus');
bc.onmessage = () => {
console.log('worker get length');
}
在加载工作程序脚本后是否有某种方法可以触发回调?
答案 0 :(得分:1)
根据最近的评论,我将我的建议写为答案:
您可以使工作程序在加载时发出一条消息,然后在主脚本上收听该消息。 这通常是我们对网络工作者的处理方式:他们向主线程发出一条消息,说“我准备好接收东西”。
可能的实现方式可能是:
// assumes the first `message` from workers is always the "loaded" ones
const loaded = w =>
new Promise(r => w.addEventListener("message", r, { once: true }));
// Code runs inside async function, so we can use `await`
async function main() {
const channel = new BroadcastChannel("my_bus");
const worker = new Worker("worker.js");
const secondWorker = new Worker("second-worker.js");
await Promise.all([
loaded(worker),
loaded(secondWorker)
]);
// this will be post only once all the workers have been loaded
channel.postMessage("1000");
}
// call the main function
main();
工人的代码如下:
const bc = new BroadcastChannel("my_bus");
bc.onmessage = () => {
console.log("worker get length");
};
postMessage("loaded");
答案 1 :(得分:0)
我发现此问题/答案试图解决与Web Workers有关的问题,因为它似乎无法立即发布给实例化的Worker。
该解决方案比为所有不同的工作人员实施已加载的消息要容易得多。只需输入一个名称即可为每个工作人员定义一个范围。
const worker = new Worker("worker.js", { name: 'worker-type-1', type: 'module' );
之所以解决了这个问题,是因为如果所有工作人员都属于同一范围(''),则如果您在实例化后立即发布给该工作人员,该工作将由的第一个可用工作人员收听。相同的范围。为新工作人员命名可以避免此问题。