2015-03-04 11:43:59 -05:00
|
|
|
ASpellWorker = require "./ASpellWorker"
|
|
|
|
_ = require "underscore"
|
2015-03-10 09:33:05 -04:00
|
|
|
logger = require 'logger-sharelatex'
|
2015-03-04 11:43:59 -05:00
|
|
|
|
|
|
|
class ASpellWorkerPool
|
2015-03-10 09:33:05 -04:00
|
|
|
MAX_REQUESTS: 100*1024
|
|
|
|
MAX_WORKERS: 32
|
|
|
|
|
2015-03-04 11:43:59 -05:00
|
|
|
constructor: (@options) ->
|
|
|
|
@PROCESS_POOL = []
|
|
|
|
@timeout = 1000
|
|
|
|
|
|
|
|
create: (language) ->
|
2015-03-10 09:33:05 -04:00
|
|
|
if @PROCESS_POOL.length >= @MAX_WORKERS
|
|
|
|
logger.log maxworkers: @MAX_WORKERS, "maximum number of workers already running"
|
|
|
|
return null
|
2015-03-04 11:43:59 -05:00
|
|
|
worker = new ASpellWorker(language, @options)
|
|
|
|
worker.pipe.on 'exit', () =>
|
|
|
|
@cleanup
|
|
|
|
@PROCESS_POOL.push(worker)
|
|
|
|
return worker
|
|
|
|
|
|
|
|
cleanup: () ->
|
|
|
|
active = @PROCESS_POOL.filter (worker) ->
|
|
|
|
worker.state != 'killed'
|
|
|
|
@PROCESS_POOL = active
|
|
|
|
|
|
|
|
check: (language, words, timeout, callback) ->
|
|
|
|
# look for an existing process in the pool
|
|
|
|
availableWorker = _.find @PROCESS_POOL, (cached) ->
|
|
|
|
cached.language == language && cached.isReady()
|
|
|
|
if not availableWorker?
|
|
|
|
worker = @create(language)
|
|
|
|
else
|
|
|
|
worker = availableWorker
|
|
|
|
|
2015-03-10 09:33:05 -04:00
|
|
|
if not worker?
|
|
|
|
# return error if too many workers
|
|
|
|
callback(new Error("no worker available"))
|
|
|
|
return
|
|
|
|
|
|
|
|
if worker.idleTimer?
|
|
|
|
clearTimeout worker.idleTimer
|
|
|
|
worker.idleTimer = null
|
|
|
|
|
|
|
|
killTimer = setTimeout () ->
|
2015-03-04 11:43:59 -05:00
|
|
|
worker.pipe.kill('SIGKILL')
|
|
|
|
, timeout || 1000
|
2015-03-10 09:33:05 -04:00
|
|
|
|
|
|
|
worker.check words, (err, output) =>
|
|
|
|
clearTimeout killTimer
|
2015-03-04 11:43:59 -05:00
|
|
|
callback(err, output)
|
2015-03-10 09:33:05 -04:00
|
|
|
# queue a shutdown if worker is not used
|
|
|
|
if worker.count > @MAX_REQUESTS
|
|
|
|
worker.shutdown("reached limit of " + @MAX_REQUESTS + " requests")
|
|
|
|
else
|
|
|
|
worker.idleTimer = setTimeout () ->
|
|
|
|
worker.shutdown("idle worker")
|
|
|
|
worker.idleTimer = null
|
|
|
|
, 1000
|
2015-03-04 11:43:59 -05:00
|
|
|
|
|
|
|
module.exports = ASpellWorkerPool
|