From d0a6754c5c9deda58d54ae3e49018a5223804392 Mon Sep 17 00:00:00 2001 From: testwhygh <46024563+testwhygh@users.noreply.github.com> Date: Wed, 25 Sep 2024 16:28:56 +0800 Subject: [PATCH] docs: An example that implements broadcast communication (#656) Co-authored-by: Carlos Fuentes (cherry picked from commit d57084a7613e6212acc50027e8a3dc41c22fb730) --- README.md | 50 ++++++++++++++++++++++++++ docs/docs/examples/broadcast.mdx | 61 ++++++++++++++++++++++++++++++++ examples/broadcast/main.js | 26 ++++++++++++++ examples/broadcast/worker.js | 12 +++++++ 4 files changed, 149 insertions(+) create mode 100644 docs/docs/examples/broadcast.mdx create mode 100644 examples/broadcast/main.js create mode 100644 examples/broadcast/worker.js diff --git a/README.md b/README.md index b253d4f3..c30d2326 100644 --- a/README.md +++ b/README.md @@ -260,6 +260,56 @@ module.exports = ({ a, b }) => { }; ``` +### Broadcast a message to all worker threads + +Piscina supports broadcast communication via BroadcastChannel(Node v18+). Here is an example, the main thread sends a message, and other threads the receive message. + +In `main.js` +```js +'use strict'; + +const { BroadcastChannel } = require('worker_threads'); +const { resolve } = require('path'); + +const Piscina = require('piscina'); +const piscina = new Piscina({ + filename: resolve(__dirname, 'worker.js'), + useAtomics: false +}); + +async function main () { + const bc = new BroadcastChannel('my_channel'); + // start worker + Promise.all([ + piscina.run('thread 1'), + piscina.run('thread 2') + ]); + // post message in one second + setTimeout(() => { + bc.postMessage('Main thread message'); + }, 1000); +} + +main(); + +``` +In `worker.js` +```js +'use strict'; +const { BroadcastChannel } = require('worker_threads'); + +module.exports = async (thread) => { + const bc = new BroadcastChannel('my_channel'); + bc.onmessage = (event) => { + console.log(thread + ' Received from:' + event.data); + }; + await new Promise((resolve) => { + setTimeout(resolve, 2000); + }); +}; + +``` + ### Additional Examples Additional examples can be found in the GitHub repo at diff --git a/docs/docs/examples/broadcast.mdx b/docs/docs/examples/broadcast.mdx new file mode 100644 index 00000000..b43e39c5 --- /dev/null +++ b/docs/docs/examples/broadcast.mdx @@ -0,0 +1,61 @@ +--- +id: Simple +sidebar_position: 23 +--- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import { WorkerWrapperComponent } from '@site/src/components/WorkerWrapper.mdx' + +In this example, we create a Piscina instance that uses BroadcastChannel(Node v18+) to implement broadcast communication. The main thread sends a message, and other threads the receive message. + + + + +```javascript title="index.js" +'use strict'; + +const { BroadcastChannel } = require('worker_threads'); +const { resolve } = require('path'); + +const Piscina = require('piscina'); +const piscina = new Piscina({ + filename: resolve(__dirname, 'worker.js'), + useAtomics: false +}); + +async function main () { + const bc = new BroadcastChannel('my_channel'); + // start worker + Promise.all([ + piscina.run('thread 1'), + piscina.run('thread 2') + ]); + // post message in one second + setTimeout(() => { + bc.postMessage('Main thread message'); + }, 1000); +} + +main(); + +``` + +```javascript title="worker.js" +'use strict'; +const { BroadcastChannel } = require('worker_threads'); + +module.exports = async (thread) => { + const bc = new BroadcastChannel('my_channel'); + bc.onmessage = (event) => { + console.log(thread + ' Received from:' + event.data); + }; + await new Promise((resolve) => { + setTimeout(resolve, 2000); + }); +}; + +``` + + + +You can also check out this example on [github](https://github.com/piscinajs/piscina/tree/current/examples/broadcast). diff --git a/examples/broadcast/main.js b/examples/broadcast/main.js new file mode 100644 index 00000000..a8f275e8 --- /dev/null +++ b/examples/broadcast/main.js @@ -0,0 +1,26 @@ +'use strict'; + +const { BroadcastChannel } = require('worker_threads'); +const { resolve } = require('path'); + +const Piscina = require('piscina'); +const piscina = new Piscina({ + filename: resolve(__dirname, 'worker.js'), + // Set useAtomics to false to avoid threads being blocked when idle + useAtomics: false +}); + +async function main () { + const bc = new BroadcastChannel('my_channel'); + // start worker + Promise.all([ + piscina.run('thread 1'), + piscina.run('thread 2') + ]); + // post message in one second + setTimeout(() => { + bc.postMessage('Main thread message'); + }, 1000); +} + +main(); diff --git a/examples/broadcast/worker.js b/examples/broadcast/worker.js new file mode 100644 index 00000000..aadc6062 --- /dev/null +++ b/examples/broadcast/worker.js @@ -0,0 +1,12 @@ +'use strict'; +const { BroadcastChannel } = require('worker_threads'); + +module.exports = async (thread) => { + const bc = new BroadcastChannel('my_channel'); + bc.onmessage = (event) => { + console.log(thread + ' Received from:' + event.data); + }; + await new Promise((resolve) => { + setTimeout(resolve, 2000); + }); +};