diff options
author | Chocobozzz <me@florianbigard.com> | 2018-09-11 16:27:07 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-09-13 14:05:49 +0200 |
commit | c48e82b5e0478434de30626d14594a97f2402e7c (patch) | |
tree | a78e5272bd0fe4f5b41831e571e02d05f1515b82 /server/initializers | |
parent | a651038487faa838bda3ce04695b08bc65baff70 (diff) | |
download | PeerTube-c48e82b5e0478434de30626d14594a97f2402e7c.tar.gz PeerTube-c48e82b5e0478434de30626d14594a97f2402e7c.tar.zst PeerTube-c48e82b5e0478434de30626d14594a97f2402e7c.zip |
Basic video redundancy implementation
Diffstat (limited to 'server/initializers')
-rw-r--r-- | server/initializers/checker.ts | 17 | ||||
-rw-r--r-- | server/initializers/constants.ts | 36 | ||||
-rw-r--r-- | server/initializers/database.ts | 4 | ||||
-rw-r--r-- | server/initializers/migrations/0270-server-redundancy.ts | 24 |
4 files changed, 77 insertions, 4 deletions
diff --git a/server/initializers/checker.ts b/server/initializers/checker.ts index 9dd104035..6a2badd35 100644 --- a/server/initializers/checker.ts +++ b/server/initializers/checker.ts | |||
@@ -7,6 +7,9 @@ import { parse } from 'url' | |||
7 | import { CONFIG } from './constants' | 7 | import { CONFIG } from './constants' |
8 | import { logger } from '../helpers/logger' | 8 | import { logger } from '../helpers/logger' |
9 | import { getServerActor } from '../helpers/utils' | 9 | import { getServerActor } from '../helpers/utils' |
10 | import { VideosRedundancy } from '../../shared/models/redundancy' | ||
11 | import { isArray } from '../helpers/custom-validators/misc' | ||
12 | import { uniq } from 'lodash' | ||
10 | 13 | ||
11 | async function checkActivityPubUrls () { | 14 | async function checkActivityPubUrls () { |
12 | const actor = await getServerActor() | 15 | const actor = await getServerActor() |
@@ -35,6 +38,20 @@ function checkConfig () { | |||
35 | return 'NSFW policy setting should be "do_not_list" or "blur" or "display" instead of ' + defaultNSFWPolicy | 38 | return 'NSFW policy setting should be "do_not_list" or "blur" or "display" instead of ' + defaultNSFWPolicy |
36 | } | 39 | } |
37 | 40 | ||
41 | const redundancyVideos = config.get<VideosRedundancy[]>('redundancy.videos') | ||
42 | if (isArray(redundancyVideos)) { | ||
43 | for (const r of redundancyVideos) { | ||
44 | if ([ 'most-views' ].indexOf(r.strategy) === -1) { | ||
45 | return 'Redundancy video entries should have "most-views" strategy instead of ' + r.strategy | ||
46 | } | ||
47 | } | ||
48 | |||
49 | const filtered = uniq(redundancyVideos.map(r => r.strategy)) | ||
50 | if (filtered.length !== redundancyVideos.length) { | ||
51 | return 'Redundancy video entries should have uniq strategies' | ||
52 | } | ||
53 | } | ||
54 | |||
38 | return null | 55 | return null |
39 | } | 56 | } |
40 | 57 | ||
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 5b7ea5d6c..6b4afbfd8 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import { IConfig } from 'config' | 1 | import { IConfig } from 'config' |
2 | import { dirname, join } from 'path' | 2 | import { dirname, join } from 'path' |
3 | import { JobType, VideoRateType, VideoState } from '../../shared/models' | 3 | import { JobType, VideoRateType, VideoRedundancyStrategy, VideoState, VideosRedundancy } from '../../shared/models' |
4 | import { ActivityPubActorType } from '../../shared/models/activitypub' | 4 | import { ActivityPubActorType } from '../../shared/models/activitypub' |
5 | import { FollowState } from '../../shared/models/actors' | 5 | import { FollowState } from '../../shared/models/actors' |
6 | import { VideoAbuseState, VideoImportState, VideoPrivacy } from '../../shared/models/videos' | 6 | import { VideoAbuseState, VideoImportState, VideoPrivacy } from '../../shared/models/videos' |
@@ -9,13 +9,14 @@ import { buildPath, isTestInstance, root, sanitizeHost, sanitizeUrl } from '../h | |||
9 | import { NSFWPolicyType } from '../../shared/models/videos/nsfw-policy.type' | 9 | import { NSFWPolicyType } from '../../shared/models/videos/nsfw-policy.type' |
10 | import { invert } from 'lodash' | 10 | import { invert } from 'lodash' |
11 | import { CronRepeatOptions, EveryRepeatOptions } from 'bull' | 11 | import { CronRepeatOptions, EveryRepeatOptions } from 'bull' |
12 | import * as bytes from 'bytes' | ||
12 | 13 | ||
13 | // Use a variable to reload the configuration if we need | 14 | // Use a variable to reload the configuration if we need |
14 | let config: IConfig = require('config') | 15 | let config: IConfig = require('config') |
15 | 16 | ||
16 | // --------------------------------------------------------------------------- | 17 | // --------------------------------------------------------------------------- |
17 | 18 | ||
18 | const LAST_MIGRATION_VERSION = 265 | 19 | const LAST_MIGRATION_VERSION = 270 |
19 | 20 | ||
20 | // --------------------------------------------------------------------------- | 21 | // --------------------------------------------------------------------------- |
21 | 22 | ||
@@ -137,7 +138,8 @@ let SCHEDULER_INTERVALS_MS = { | |||
137 | badActorFollow: 60000 * 60, // 1 hour | 138 | badActorFollow: 60000 * 60, // 1 hour |
138 | removeOldJobs: 60000 * 60, // 1 hour | 139 | removeOldJobs: 60000 * 60, // 1 hour |
139 | updateVideos: 60000, // 1 minute | 140 | updateVideos: 60000, // 1 minute |
140 | youtubeDLUpdate: 60000 * 60 * 24 // 1 day | 141 | youtubeDLUpdate: 60000 * 60 * 24, // 1 day |
142 | videosRedundancy: 60000 * 2 // 2 hours | ||
141 | } | 143 | } |
142 | 144 | ||
143 | // --------------------------------------------------------------------------- | 145 | // --------------------------------------------------------------------------- |
@@ -208,6 +210,9 @@ const CONFIG = { | |||
208 | INTERVAL_DAYS: config.get<number>('trending.videos.interval_days') | 210 | INTERVAL_DAYS: config.get<number>('trending.videos.interval_days') |
209 | } | 211 | } |
210 | }, | 212 | }, |
213 | REDUNDANCY: { | ||
214 | VIDEOS: buildVideosRedundancy(config.get<any[]>('redundancy.videos')) | ||
215 | }, | ||
211 | ADMIN: { | 216 | ADMIN: { |
212 | get EMAIL () { return config.get<string>('admin.email') } | 217 | get EMAIL () { return config.get<string>('admin.email') } |
213 | }, | 218 | }, |
@@ -321,6 +326,9 @@ const CONSTRAINTS_FIELDS = { | |||
321 | } | 326 | } |
322 | } | 327 | } |
323 | }, | 328 | }, |
329 | VIDEOS_REDUNDANCY: { | ||
330 | URL: { min: 3, max: 2000 } // Length | ||
331 | }, | ||
324 | VIDEOS: { | 332 | VIDEOS: { |
325 | NAME: { min: 3, max: 120 }, // Length | 333 | NAME: { min: 3, max: 120 }, // Length |
326 | LANGUAGE: { min: 1, max: 10 }, // Length | 334 | LANGUAGE: { min: 1, max: 10 }, // Length |
@@ -584,6 +592,13 @@ const CACHE = { | |||
584 | } | 592 | } |
585 | } | 593 | } |
586 | 594 | ||
595 | const REDUNDANCY = { | ||
596 | VIDEOS: { | ||
597 | EXPIRES_AFTER_MS: 48 * 3600 * 1000, // 2 days | ||
598 | RANDOMIZED_FACTOR: 5 | ||
599 | } | ||
600 | } | ||
601 | |||
587 | const ACCEPT_HEADERS = [ 'html', 'application/json' ].concat(ACTIVITY_PUB.POTENTIAL_ACCEPT_HEADERS) | 602 | const ACCEPT_HEADERS = [ 'html', 'application/json' ].concat(ACTIVITY_PUB.POTENTIAL_ACCEPT_HEADERS) |
588 | 603 | ||
589 | // --------------------------------------------------------------------------- | 604 | // --------------------------------------------------------------------------- |
@@ -629,8 +644,11 @@ if (isTestInstance() === true) { | |||
629 | SCHEDULER_INTERVALS_MS.badActorFollow = 10000 | 644 | SCHEDULER_INTERVALS_MS.badActorFollow = 10000 |
630 | SCHEDULER_INTERVALS_MS.removeOldJobs = 10000 | 645 | SCHEDULER_INTERVALS_MS.removeOldJobs = 10000 |
631 | SCHEDULER_INTERVALS_MS.updateVideos = 5000 | 646 | SCHEDULER_INTERVALS_MS.updateVideos = 5000 |
647 | SCHEDULER_INTERVALS_MS.videosRedundancy = 5000 | ||
632 | REPEAT_JOBS['videos-views'] = { every: 5000 } | 648 | REPEAT_JOBS['videos-views'] = { every: 5000 } |
633 | 649 | ||
650 | REDUNDANCY.VIDEOS.RANDOMIZED_FACTOR = 1 | ||
651 | |||
634 | VIDEO_VIEW_LIFETIME = 1000 // 1 second | 652 | VIDEO_VIEW_LIFETIME = 1000 // 1 second |
635 | 653 | ||
636 | JOB_ATTEMPTS['email'] = 1 | 654 | JOB_ATTEMPTS['email'] = 1 |
@@ -653,6 +671,7 @@ export { | |||
653 | CONFIG, | 671 | CONFIG, |
654 | CONSTRAINTS_FIELDS, | 672 | CONSTRAINTS_FIELDS, |
655 | EMBED_SIZE, | 673 | EMBED_SIZE, |
674 | REDUNDANCY, | ||
656 | JOB_CONCURRENCY, | 675 | JOB_CONCURRENCY, |
657 | JOB_ATTEMPTS, | 676 | JOB_ATTEMPTS, |
658 | LAST_MIGRATION_VERSION, | 677 | LAST_MIGRATION_VERSION, |
@@ -722,6 +741,17 @@ function updateWebserverConfig () { | |||
722 | CONFIG.WEBSERVER.HOST = sanitizeHost(CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT, REMOTE_SCHEME.HTTP) | 741 | CONFIG.WEBSERVER.HOST = sanitizeHost(CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT, REMOTE_SCHEME.HTTP) |
723 | } | 742 | } |
724 | 743 | ||
744 | function buildVideosRedundancy (objs: { strategy: VideoRedundancyStrategy, size: string }[]): VideosRedundancy[] { | ||
745 | if (!objs) return [] | ||
746 | |||
747 | return objs.map(obj => { | ||
748 | return { | ||
749 | strategy: obj.strategy, | ||
750 | size: bytes.parse(obj.size) | ||
751 | } | ||
752 | }) | ||
753 | } | ||
754 | |||
725 | function buildLanguages () { | 755 | function buildLanguages () { |
726 | const iso639 = require('iso-639-3') | 756 | const iso639 = require('iso-639-3') |
727 | 757 | ||
diff --git a/server/initializers/database.ts b/server/initializers/database.ts index b68e1a882..4d57bf8aa 100644 --- a/server/initializers/database.ts +++ b/server/initializers/database.ts | |||
@@ -27,6 +27,7 @@ import { VideoCaptionModel } from '../models/video/video-caption' | |||
27 | import { VideoImportModel } from '../models/video/video-import' | 27 | import { VideoImportModel } from '../models/video/video-import' |
28 | import { VideoViewModel } from '../models/video/video-views' | 28 | import { VideoViewModel } from '../models/video/video-views' |
29 | import { VideoChangeOwnershipModel } from '../models/video/video-change-ownership' | 29 | import { VideoChangeOwnershipModel } from '../models/video/video-change-ownership' |
30 | import { VideoRedundancyModel } from '../models/redundancy/video-redundancy' | ||
30 | 31 | ||
31 | require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string | 32 | require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string |
32 | 33 | ||
@@ -87,7 +88,8 @@ async function initDatabaseModels (silent: boolean) { | |||
87 | VideoCommentModel, | 88 | VideoCommentModel, |
88 | ScheduleVideoUpdateModel, | 89 | ScheduleVideoUpdateModel, |
89 | VideoImportModel, | 90 | VideoImportModel, |
90 | VideoViewModel | 91 | VideoViewModel, |
92 | VideoRedundancyModel | ||
91 | ]) | 93 | ]) |
92 | 94 | ||
93 | // Check extensions exist in the database | 95 | // Check extensions exist in the database |
diff --git a/server/initializers/migrations/0270-server-redundancy.ts b/server/initializers/migrations/0270-server-redundancy.ts new file mode 100644 index 000000000..903ba8a85 --- /dev/null +++ b/server/initializers/migrations/0270-server-redundancy.ts | |||
@@ -0,0 +1,24 @@ | |||
1 | import * as Sequelize from 'sequelize' | ||
2 | |||
3 | async function up (utils: { | ||
4 | transaction: Sequelize.Transaction | ||
5 | queryInterface: Sequelize.QueryInterface | ||
6 | sequelize: Sequelize.Sequelize | ||
7 | }): Promise<any> { | ||
8 | { | ||
9 | const data = { | ||
10 | type: Sequelize.BOOLEAN, | ||
11 | allowNull: false, | ||
12 | defaultValue: false | ||
13 | } | ||
14 | |||
15 | await utils.queryInterface.addColumn('server', 'redundancyAllowed', data) | ||
16 | } | ||
17 | |||
18 | } | ||
19 | |||
20 | function down (options) { | ||
21 | throw new Error('Not implemented.') | ||
22 | } | ||
23 | |||
24 | export { up, down } | ||