refact(encode): add back worker pool

This commit is contained in:
wryk 2019-05-20 21:29:20 +02:00
parent 7c33858bbc
commit 5294724527

View file

@ -1,5 +1,12 @@
import genericPool from 'generic-pool'
import { calcProgress } from '/services/util.js'
import { task, do as taskDo, waitAll } from 'folktale/concurrency/task'
import {
task,
do as taskDo,
of as taskOf,
fromPromised as taskFromPromised,
waitAll
} from 'folktale/concurrency/task'
import { GIF_PALETTE_SIZE } from '/constants.js'
@ -23,10 +30,31 @@ export function encode ({ imageDataList, imageWidth, imageHeight, delayTime }, {
}
function quantizeColorImageDataList (imageDataList, paletteSize, progressCallback) {
return task((resolver) => {
const workerPool = genericPool.createPool({
create: () => new Worker('/services/quantize-color.worker.js'),
destroy: worker => worker.terminate()
}, {
min: 0,
max: 2
})
resolver.cleanup(() => {
workerPool.drain()
})
let complete = 0
const acquireWorker = taskFromPromised(() => workerPool.acquire())
const releaseWorker = taskFromPromised((worker) => workerPool.release(worker))
const tasks = imageDataList
.map(imageData => quantizeColorImageData(imageData, paletteSize))
.map(imageData => taskDo(function * () {
const worker = yield acquireWorker()
const indexedColorImage = yield quantizeColorImageData(worker, imageData, paletteSize)
releaseWorker(worker).run()
return taskOf(indexedColorImage)
}))
.map(task => {
return task.map(x => {
progressCallback(++complete / imageDataList.length)
@ -34,15 +62,24 @@ function quantizeColorImageDataList (imageDataList, paletteSize, progressCallbac
})
})
return waitAll(tasks)
const execution = waitAll(tasks).run()
resolver.onCancelled(() => { execution.cancel() })
execution.listen({
onCancelled: resolver.cancel,
onRejected: resolver.reject,
onResolved: resolver.resolve
})
})
}
function quantizeColorImageData (imageData, paletteSize) {
function quantizeColorImageData (worker, imageData, paletteSize) {
return task((resolver) => {
const worker = new Worker('/services/quantize-color.worker.js')
resolver.cleanup(() => {
worker.terminate()
worker.onerror = null
worker.onmessageerror = null
worker.onmessage = null
})
worker.onerror = resolver.reject