1 import * as Sequelize from 'sequelize'
2 import { AllowNull, Column, CreatedAt, Default, Is, IsInt, Max, Model, Table, UpdatedAt } from 'sequelize-typescript'
3 import { isHostValid } from '../../helpers/custom-validators/servers'
4 import { logger } from '../../helpers/logger'
5 import { SERVERS_SCORE } from '../../initializers'
6 import { throwIfNotValid } from '../utils'
20 export class ServerModel extends Model<ServerModel> {
23 @Is('Host', value => throwIfNotValid(value, isHostValid, 'valid host'))
28 @Default(SERVERS_SCORE.BASE)
30 @Max(SERVERS_SCORE.MAX)
40 static updateServersScoreAndRemoveBadOnes (goodServers: number[], badServers: number[]) {
41 logger.info('Updating %d good servers and %d bad servers scores.', goodServers.length, badServers.length)
43 if (goodServers.length !== 0) {
44 ServerModel.incrementScores(goodServers, SERVERS_SCORE.BONUS)
46 logger.error('Cannot increment scores of good servers.', err)
50 if (badServers.length !== 0) {
51 ServerModel.incrementScores(badServers, SERVERS_SCORE.PENALTY)
52 .then(() => ServerModel.removeBadServers())
54 if (err) logger.error('Cannot decrement scores of bad servers.', err)
60 // Remove servers with a score of 0 (too many requests where they were unreachable)
61 private static async removeBadServers () {
63 const servers = await ServerModel.listBadServers()
65 const serversRemovePromises = servers.map(server => server.destroy())
66 await Promise.all(serversRemovePromises)
68 const numberOfServersRemoved = servers.length
70 if (numberOfServersRemoved) {
71 logger.info('Removed %d servers.', numberOfServersRemoved)
73 logger.info('No need to remove bad servers.')
76 logger.error('Cannot remove bad servers.', err)
80 private static incrementScores (ids: number[], value: number) {
82 score: Sequelize.literal('score +' + value)
88 [Sequelize.Op.in]: ids
91 // In this case score is a literal and not an integer so we do not validate it
95 return ServerModel.update(update, options)
98 private static listBadServers () {
102 [Sequelize.Op.lte]: 0
107 return ServerModel.findAll(query)