Skip to content

Instantly share code, notes, and snippets.

@timdp
Created April 4, 2021 21:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timdp/97ce4bfcc2ea43ff746e369173af52ec to your computer and use it in GitHub Desktop.
Save timdp/97ce4bfcc2ea43ff746e369173af52ec to your computer and use it in GitHub Desktop.
AVA Shared Worker utils
const createDebug = require('debug')
const { serializeError } = require('serialize-error')
const receiveCommands = async (main, commands, debug) => {
for await (const message of main.subscribe()) {
if (message.data == null || typeof message.data.type !== 'string') {
debug('unexpected message', { message })
continue
}
const { type, payload } = message.data
const data = {}
debug('invoking command', { type, payload })
try {
const result = await commands[type](payload)
debug('command succeeded', { type, result })
data.result = result
} catch (error) {
debug('command failed', { type, error })
data.error = serializeError(error)
} finally {
debug('acknowledging command', { type, data })
try {
await message.reply(data)
debug('acknowledgment succeeded', { type })
} catch (error) {
debug('acknowledgment failed', { type, error })
}
}
}
}
const createWorker = (id, init, dispose, commands) => async ({
negotiateProtocol
}) => {
const debug = createDebug(`browsertest:${id}:proc`)
const main = negotiateProtocol(['experimental'])
await init()
main.ready()
const commandsWithDispose = {
...commands,
_dispose: async () => {
debug('disposing')
try {
await dispose()
debug('disposal succeeded')
} catch (error) {
debug('disposal failed', { error })
}
}
}
await receiveCommands(main, commandsWithDispose, debug)
}
module.exports = createWorker
const createDebug = require('debug')
const { registerSharedWorker } = require('ava/plugin')
const sendCommand = require('./send-command')
const registerWorker = (id, filename) => {
const worker = registerSharedWorker({
filename,
supportedProtocols: ['experimental'],
teardown: async () => {
await sendCommand(worker, '_dispose')
}
})
worker._debug = createDebug(`browsertest:${id}:remote`)
return worker
}
module.exports = registerWorker
const { deserializeError } = require('serialize-error')
const sendCommand = async (worker, type, payload = {}) => {
const debug = worker._debug
debug('sending command', { type, payload })
const { replies } = await worker.publish({ type, payload })
debug('sent command', { type })
const iter = await replies().next()
const {
data: { result, error }
} = iter.value
debug('got command response', { type, result, error })
if (error != null) {
throw deserializeError(error)
}
return result
}
module.exports = sendCommand
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment