All files / src autoRetry.coffee

46.34% Statements 19/41
0% Branches 0/5
0% Functions 0/19
47.5% Lines 19/40
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 971x 1x 1x 1x 1x 1x 1x   1x         1x                 1x   1x                                     1x                       1x                                                         1x         1x     1x 1x 1x 1x  
logger = require "winston"
moment = require 'moment'
Q = require 'q'
Channels = require('./model/channels')
Channel = Channels.Channel
AutoRetry = require('./model/autoRetry').AutoRetry
Task = require('./model/tasks').Task
 
exports.reachedMaxAttempts = (tx, channel) ->
  return channel.autoRetryMaxAttempts? and
  channel.autoRetryMaxAttempts > 0 and
  tx.autoRetryAttempt >= channel.autoRetryMaxAttempts
 
exports.queueForRetry = (tx) ->
  retry = new AutoRetry
    transactionID: tx._id
    channelID: tx.channelID
    requestTimestamp: tx.request.timestamp
  retry.save (err) ->
    if err
      logger.error "Failed to queue transaction #{tx._id} for auto retry: #{err}"
 
getChannels = (callback) -> Channel.find autoRetryEnabled: true, status: 'enabled', callback
 
popTransactions = (channel, callback) ->
  to = moment().subtract channel.autoRetryPeriodMinutes-1, 'minutes'
 
  query =
    $and: [
        channelID: channel._id
      ,
        'requestTimestamp':
          $lte: to.toDate()
    ]
 
  logger.debug "Executing query autoRetry.findAndRemove(#{JSON.stringify query})"
  AutoRetry.find query, (err, transactions) ->
    return callback err if err
    return callback null, [] if transactions.length is 0
    AutoRetry.remove _id: $in: (transactions.map (t) -> t._id), (err) ->
      return callback err if err
      callback null, transactions
 
createRerunTask = (transactionIDs, callback) ->
  logger.info "Rerunning failed transactions: #{transactionIDs}"
  task = new Task
    transactions: (transactionIDs.map (t) -> tid: t )
    totalTransactions: transactionIDs.length
    remainingTransactions: transactionIDs.length
    user: 'internal'
 
  task.save (err) ->
    logger.error err if err
    callback()
 
autoRetryTask = (job, done) ->
  _taskStart = new Date()
  transactionsToRerun = []
 
  getChannels (err, results) ->
    promises = []
 
    for channel in results
      do (channel) ->
        deferred = Q.defer()
 
        popTransactions channel, (err, results) ->
          if err
            logger.error err
          else if results? and results.length>0
            transactionsToRerun.push tid for tid in (results.map((r) -> r.transactionID))
          deferred.resolve()
 
        promises.push deferred.promise
 
    (Q.all promises).then ->
      end = ->
        logger.debug "Auto retry task total time: #{new Date()-_taskStart} ms"
        done()
      if transactionsToRerun.length > 0
        createRerunTask transactionsToRerun, end
      else end()
 
 
setupAgenda = (agenda) ->
  agenda.define 'auto retry failed transactions', (job, done) -> autoRetryTask job, done
  agenda.every '1 minutes', 'auto retry failed transactions'
 
 
exports.setupAgenda = setupAgenda
 
if process.env.NODE_ENV is "test"
  exports.getChannels = getChannels
  exports.popTransactions = popTransactions
  exports.createRerunTask = createRerunTask
  exports.autoRetryTask = autoRetryTask