mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
77 lines
2.3 KiB
CoffeeScript
77 lines
2.3 KiB
CoffeeScript
ASpellWorker = require "./ASpellWorker"
|
|
_ = require "underscore"
|
|
logger = require 'logger-sharelatex'
|
|
metrics = require('metrics-sharelatex')
|
|
|
|
class ASpellWorkerPool
|
|
MAX_REQUESTS: 100*1024
|
|
MAX_WORKERS: 32
|
|
MAX_IDLE_TIME: 1000
|
|
MAX_REQUEST_TIME: 60*1000
|
|
|
|
constructor: (@options) ->
|
|
@PROCESS_POOL = []
|
|
|
|
create: (language) ->
|
|
if @PROCESS_POOL.length >= @MAX_WORKERS
|
|
logger.log maxworkers: @MAX_WORKERS, "maximum number of workers already running"
|
|
return null
|
|
worker = new ASpellWorker(language, @options)
|
|
worker.pipe.on 'exit', () =>
|
|
if worker.killTimer?
|
|
clearTimeout worker.killTimer
|
|
worker.killTimer = null
|
|
if worker.idleTimer?
|
|
clearTimeout worker.idleTimer
|
|
worker.idleTimer = null
|
|
logger.log process: worker.pipe.pid, lang: language, "removing aspell worker from pool"
|
|
@cleanup()
|
|
@PROCESS_POOL.push(worker)
|
|
metrics.gauge 'aspellWorkerPool-size', @PROCESS_POOL.length
|
|
return worker
|
|
|
|
cleanup: () ->
|
|
active = @PROCESS_POOL.filter (worker) ->
|
|
worker.state != 'killed'
|
|
@PROCESS_POOL = active
|
|
metrics.gauge 'aspellWorkerPool-size', @PROCESS_POOL.length
|
|
|
|
check: (language, words, timeout, callback) ->
|
|
logger.log lang: language, words: words.length, timeout: timeout, "aspell worker running check"
|
|
# 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
|
|
|
|
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
|
|
|
|
worker.killTimer = setTimeout () ->
|
|
worker.kill("spell check timed out")
|
|
, timeout || @MAX_REQUEST_TIME
|
|
|
|
worker.check words, (err, output) =>
|
|
if worker.killTimer?
|
|
clearTimeout worker.killTimer
|
|
worker.killTimer = null
|
|
callback(err, output)
|
|
return if err? # process has shut down
|
|
if worker.count > @MAX_REQUESTS
|
|
worker.shutdown("reached limit of " + @MAX_REQUESTS + " requests")
|
|
else
|
|
# queue a shutdown if worker is idle
|
|
worker.idleTimer = setTimeout () ->
|
|
worker.shutdown("idle worker")
|
|
worker.idleTimer = null
|
|
, @MAX_IDLE_TIME
|
|
|
|
module.exports = ASpellWorkerPool
|