X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fmodels%2Fserver%2Fserver.ts;h=ef42de09063b0f5ed7bf9d511e7d7d01c4fe65cf;hb=70c6a848a43868d826453da11d212fa96956fb0c;hp=26fa8755095934df7eed66f8ea191e68e280cfb6;hpb=608624252466acf9f1d9ee1c1170bd4fe4d18d18;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/models/server/server.ts b/server/models/server/server.ts index 26fa87550..ef42de090 100644 --- a/server/models/server/server.ts +++ b/server/models/server/server.ts @@ -1,233 +1,92 @@ -import { map } from 'lodash' -import * as Sequelize from 'sequelize' - -import { FRIEND_SCORE, SERVERS_SCORE } from '../../initializers' -import { logger, isHostValid } from '../../helpers' - -import { addMethodsToModel, getSort } from '../utils' -import { - ServerInstance, - ServerAttributes, - - ServerMethods -} from './server-interface' - -let Server: Sequelize.Model -let countAll: ServerMethods.CountAll -let incrementScores: ServerMethods.IncrementScores -let list: ServerMethods.List -let listForApi: ServerMethods.ListForApi -let listAllIds: ServerMethods.ListAllIds -let listRandomServerIdsWithRequest: ServerMethods.ListRandomServerIdsWithRequest -let listBadServers: ServerMethods.ListBadServers -let load: ServerMethods.Load -let loadByHost: ServerMethods.LoadByHost -let removeAll: ServerMethods.RemoveAll -let updateServersScore: ServerMethods.UpdateServersScore - -export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) { - Server = sequelize.define('Server', - { - host: { - type: DataTypes.STRING, - allowNull: false, - validate: { - isHost: value => { - const res = isHostValid(value) - if (res === false) throw new Error('Host not valid.') - } - } - }, - score: { - type: DataTypes.INTEGER, - defaultValue: FRIEND_SCORE.BASE, - allowNull: false, - validate: { - isInt: true, - max: FRIEND_SCORE.MAX - } - } - }, +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 { ActorModel } from '../actor/actor' +import { throwIfNotValid } from '../utils' +import { ServerBlocklistModel } from './server-blocklist' + +@Table({ + tableName: 'server', + indexes: [ { - indexes: [ - { - fields: [ 'host' ], - unique: true - }, - { - fields: [ 'score' ] - } - ] + fields: [ 'host' ], + unique: true } - ) - - const classMethods = [ - countAll, - incrementScores, - list, - listForApi, - listAllIds, - listRandomServerIdsWithRequest, - listBadServers, - load, - loadByHost, - updateServersScore, - removeAll ] - addMethodsToModel(Server, classMethods) +}) +export class ServerModel extends Model>> { - return Server -} + @AllowNull(false) + @Is('Host', value => throwIfNotValid(value, isHostValid, 'valid host')) + @Column + host: string -// ------------------------------ Statics ------------------------------ + @AllowNull(false) + @Default(false) + @Column + redundancyAllowed: boolean -countAll = function () { - return Server.count() -} + @CreatedAt + createdAt: Date -incrementScores = function (ids: number[], value: number) { - const update = { - score: Sequelize.literal('score +' + value) - } + @UpdatedAt + updatedAt: Date - const options = { - where: { - id: { - [Sequelize.Op.in]: ids - } + @HasMany(() => ActorModel, { + foreignKey: { + name: 'serverId', + allowNull: true }, - // In this case score is a literal and not an integer so we do not validate it - validate: false - } - - return Server.update(update, options) -} - -list = function () { - return Server.findAll() -} - -listForApi = function (start: number, count: number, sort: string) { - const query = { - offset: start, - limit: count, - order: [ getSort(sort) ] - } - - return Server.findAndCountAll(query).then(({ rows, count }) => { - return { - data: rows, - total: count - } + onDelete: 'CASCADE', + hooks: true }) -} - -listAllIds = function (transaction: Sequelize.Transaction) { - const query = { - attributes: [ 'id' ], - transaction - } + Actors: ActorModel[] - return Server.findAll(query).then(servers => { - return map(servers, 'id') + @HasMany(() => ServerBlocklistModel, { + foreignKey: { + allowNull: false + }, + onDelete: 'CASCADE' }) -} - -listRandomServerIdsWithRequest = function (limit: number, tableWithServers: string, tableWithServersJoins: string) { - return Server.count().then(count => { - // Optimization... - if (count === 0) return [] - - let start = Math.floor(Math.random() * count) - limit - if (start < 0) start = 0 + BlockedBy: ServerBlocklistModel[] - const subQuery = `(SELECT DISTINCT "${tableWithServers}"."serverId" FROM "${tableWithServers}" ${tableWithServersJoins})` + static load (id: number, transaction?: Transaction): Promise { const query = { - attributes: [ 'id' ], - order: [ - [ 'id', 'ASC' ] - ], - offset: start, - limit: limit, where: { - id: { - [Sequelize.Op.in]: Sequelize.literal(subQuery) - } - } + id + }, + transaction } - return Server.findAll(query).then(servers => { - return map(servers, 'id') - }) - }) -} + return ServerModel.findOne(query) + } -listBadServers = function () { - const query = { - where: { - score: { - [Sequelize.Op.lte]: 0 + static loadByHost (host: string): Promise { + const query = { + where: { + host } } - } - - return Server.findAll(query) -} -load = function (id: number) { - return Server.findById(id) -} - -loadByHost = function (host: string) { - const query = { - where: { - host: host - } + return ServerModel.findOne(query) } - return Server.findOne(query) -} - -removeAll = function () { - return Server.destroy() -} - -updateServersScore = function (goodServers: number[], badServers: number[]) { - logger.info('Updating %d good servers and %d bad servers scores.', goodServers.length, badServers.length) + static async loadOrCreateByHost (host: string) { + let server = await ServerModel.loadByHost(host) + if (!server) server = await ServerModel.create({ host }) - if (goodServers.length !== 0) { - incrementScores(goodServers, SERVERS_SCORE.BONUS).catch(err => { - logger.error('Cannot increment scores of good servers.', err) - }) + return server } - if (badServers.length !== 0) { - incrementScores(badServers, SERVERS_SCORE.PENALTY) - .then(() => removeBadServers()) - .catch(err => { - if (err) logger.error('Cannot decrement scores of bad servers.', err) - }) + isBlocked () { + return this.BlockedBy && this.BlockedBy.length !== 0 } -} - -// --------------------------------------------------------------------------- - -// Remove servers with a score of 0 (too many requests where they were unreachable) -async function removeBadServers () { - try { - const servers = await 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.') + toFormattedJSON (this: MServerFormattable) { + return { + host: this.host } - } catch (err) { - logger.error('Cannot remove bad servers.', err) } }