| 123456789101112131415161718192021222324252627282930313233343536373839 |
- Settings = require('settings-sharelatex')
- logger = require('logger-sharelatex')
- Metrics = require('./Metrics')
- module.exports = class RateLimiter
- constructor: (number = 10) ->
- @ActiveWorkerCount = 0
- @CurrentWorkerLimit = number
- @BaseWorkerCount = number
- _adjustLimitUp: () ->
- @CurrentWorkerLimit += 0.1 # allow target worker limit to increase gradually
- Metrics.gauge "currentLimit", Math.ceil(@CurrentWorkerLimit)
- _adjustLimitDown: () ->
- @CurrentWorkerLimit = Math.max @BaseWorkerCount, (@CurrentWorkerLimit * 0.9)
- logger.log {currentLimit: Math.ceil(@CurrentWorkerLimit)}, "reducing rate limit"
- Metrics.gauge "currentLimit", Math.ceil(@CurrentWorkerLimit)
- _trackAndRun: (task, callback = () ->) ->
- @ActiveWorkerCount++
- Metrics.gauge "processingUpdates", @ActiveWorkerCount
- task (err) =>
- @ActiveWorkerCount--
- Metrics.gauge "processingUpdates", @ActiveWorkerCount
- callback(err)
- run: (task, callback) ->
- if @ActiveWorkerCount < @CurrentWorkerLimit
- @_trackAndRun task # below the limit, just put the task in the background
- callback() # return immediately
- if @CurrentWorkerLimit > @BaseWorkerCount
- @_adjustLimitDown()
- else
- logger.log {active: @ActiveWorkerCount, currentLimit: Math.ceil(@CurrentWorkerLimit)}, "hit rate limit"
- @_trackAndRun task, (err) =>
- @_adjustLimitUp() if !err? # don't increment rate limit if there was an error
- callback(err) # only return after task completes
|