-import * as Sequelize from 'sequelize'
-import { AllowNull, Column, CreatedAt, Default, Is, IsInt, Max, Model, Table, UpdatedAt } from 'sequelize-typescript'
+import { Transaction } from 'sequelize'
+import { AllowNull, Column, CreatedAt, Default, HasMany, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
+import { MServer, MServerFormattable } from '@server/types/models/server'
+import { AttributesOnly } from '@shared/typescript-utils'
import { isHostValid } from '../../helpers/custom-validators/servers'
-import { logger } from '../../helpers/logger'
-import { SERVERS_SCORE } from '../../initializers'
+import { ActorModel } from '../actor/actor'
import { throwIfNotValid } from '../utils'
+import { ServerBlocklistModel } from './server-blocklist'
@Table({
tableName: 'server',
{
fields: [ 'host' ],
unique: true
- },
- {
- fields: [ 'score' ]
}
]
})
-export class ServerModel extends Model<ServerModel> {
+export class ServerModel extends Model<Partial<AttributesOnly<ServerModel>>> {
@AllowNull(false)
@Is('Host', value => throwIfNotValid(value, isHostValid, 'valid host'))
host: string
@AllowNull(false)
- @Default(SERVERS_SCORE.BASE)
- @IsInt
- @Max(SERVERS_SCORE.max)
+ @Default(false)
@Column
- score: number
+ redundancyAllowed: boolean
@CreatedAt
createdAt: Date
@UpdatedAt
updatedAt: Date
- static updateServersScoreAndRemoveBadOnes (goodServers: number[], badServers: number[]) {
- logger.info('Updating %d good servers and %d bad servers scores.', goodServers.length, badServers.length)
+ @HasMany(() => ActorModel, {
+ foreignKey: {
+ name: 'serverId',
+ allowNull: true
+ },
+ onDelete: 'CASCADE',
+ hooks: true
+ })
+ Actors: ActorModel[]
+
+ @HasMany(() => ServerBlocklistModel, {
+ foreignKey: {
+ allowNull: false
+ },
+ onDelete: 'CASCADE'
+ })
+ BlockedBy: ServerBlocklistModel[]
- if (goodServers.length !== 0) {
- ServerModel.incrementScores(goodServers, SERVERS_SCORE.BONUS)
- .catch(err => {
- logger.error('Cannot increment scores of good servers.', err)
- })
+ static load (id: number, transaction?: Transaction): Promise<MServer> {
+ const query = {
+ where: {
+ id
+ },
+ transaction
}
- if (badServers.length !== 0) {
- ServerModel.incrementScores(badServers, SERVERS_SCORE.PENALTY)
- .then(() => ServerModel.removeBadServers())
- .catch(err => {
- if (err) logger.error('Cannot decrement scores of bad servers.', err)
- })
-
- }
+ return ServerModel.findOne(query)
}
- // Remove servers with a score of 0 (too many requests where they were unreachable)
- private static async removeBadServers () {
- try {
- const servers = await ServerModel.listBadServers()
-
- const serversRemovePromises = servers.map(server => server.destroy())
- await Promise.all(serversRemovePromises)
-
- const numberOfServersRemoved = servers.length
-
- if (numberOfServersRemoved) {
- logger.info('Removed %d servers.', numberOfServersRemoved)
- } else {
- logger.info('No need to remove bad servers.')
+ static loadByHost (host: string): Promise<MServer> {
+ const query = {
+ where: {
+ host
}
- } catch (err) {
- logger.error('Cannot remove bad servers.', err)
}
+
+ return ServerModel.findOne(query)
}
- private static incrementScores (ids: number[], value: number) {
- const update = {
- score: Sequelize.literal('score +' + value)
- }
+ static async loadOrCreateByHost (host: string) {
+ let server = await ServerModel.loadByHost(host)
+ if (!server) server = await ServerModel.create({ host })
- const options = {
- where: {
- id: {
- [Sequelize.Op.in]: ids
- }
- },
- // In this case score is a literal and not an integer so we do not validate it
- validate: false
- }
+ return server
+ }
- return ServerModel.update(update, options)
+ isBlocked () {
+ return this.BlockedBy && this.BlockedBy.length !== 0
}
- private static listBadServers () {
- const query = {
- where: {
- score: {
- [Sequelize.Op.lte]: 0
- }
- }
+ toFormattedJSON (this: MServerFormattable) {
+ return {
+ host: this.host
}
-
- return ServerModel.findAll(query)
}
}