aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--server/initializers/constants.ts4
-rw-r--r--server/lib/redis.ts2
-rw-r--r--server/lib/views/shared/video-viewers.ts7
-rw-r--r--server/lib/views/video-views-manager.ts18
-rw-r--r--server/models/view/local-video-viewer.ts7
-rw-r--r--server/models/view/video-view.ts7
6 files changed, 39 insertions, 6 deletions
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts
index 4929923dc..9afbc5aea 100644
--- a/server/initializers/constants.ts
+++ b/server/initializers/constants.ts
@@ -367,7 +367,7 @@ const CONSTRAINTS_FIELDS = {
367 367
368const VIEW_LIFETIME = { 368const VIEW_LIFETIME = {
369 VIEW: CONFIG.VIEWS.VIDEOS.IP_VIEW_EXPIRATION, 369 VIEW: CONFIG.VIEWS.VIDEOS.IP_VIEW_EXPIRATION,
370 VIEWER: 60000 * 5, // 5 minutes 370 VIEWER_COUNTER: 60000 * 5, // 5 minutes
371 VIEWER_STATS: 60000 * 60 // 1 hour 371 VIEWER_STATS: 60000 * 60 // 1 hour
372} 372}
373 373
@@ -845,7 +845,7 @@ if (isTestInstance() === true) {
845 845
846 REDUNDANCY.VIDEOS.RANDOMIZED_FACTOR = 1 846 REDUNDANCY.VIDEOS.RANDOMIZED_FACTOR = 1
847 847
848 VIEW_LIFETIME.VIEWER = 1000 * 5 // 5 second 848 VIEW_LIFETIME.VIEWER_COUNTER = 1000 * 5 // 5 second
849 VIEW_LIFETIME.VIEWER_STATS = 1000 * 5 // 5 second 849 VIEW_LIFETIME.VIEWER_STATS = 1000 * 5 // 5 second
850 CONTACT_FORM_LIFETIME = 1000 // 1 second 850 CONTACT_FORM_LIFETIME = 1000 // 1 second
851 851
diff --git a/server/lib/redis.ts b/server/lib/redis.ts
index b86aefa0e..f9cea57cd 100644
--- a/server/lib/redis.ts
+++ b/server/lib/redis.ts
@@ -146,7 +146,7 @@ class Redis {
146 } 146 }
147 147
148 setIPVideoViewer (ip: string, videoUUID: string) { 148 setIPVideoViewer (ip: string, videoUUID: string) {
149 return this.setValue(this.generateIPViewerKey(ip, videoUUID), '1', VIEW_LIFETIME.VIEWER) 149 return this.setValue(this.generateIPViewerKey(ip, videoUUID), '1', VIEW_LIFETIME.VIEWER_COUNTER)
150 } 150 }
151 151
152 async doesVideoIPViewExist (ip: string, videoUUID: string) { 152 async doesVideoIPViewExist (ip: string, videoUUID: string) {
diff --git a/server/lib/views/shared/video-viewers.ts b/server/lib/views/shared/video-viewers.ts
index 5c26f8982..4dad1f0e8 100644
--- a/server/lib/views/shared/video-viewers.ts
+++ b/server/lib/views/shared/video-viewers.ts
@@ -41,7 +41,7 @@ export class VideoViewers {
41 private processingViewerStats = false 41 private processingViewerStats = false
42 42
43 constructor () { 43 constructor () {
44 setInterval(() => this.cleanViewerCounters(), VIEW_LIFETIME.VIEWER) 44 setInterval(() => this.cleanViewerCounters(), VIEW_LIFETIME.VIEWER_COUNTER)
45 45
46 setInterval(() => this.processViewerStats(), VIEW_LIFETIME.VIEWER_STATS) 46 setInterval(() => this.processViewerStats(), VIEW_LIFETIME.VIEWER_STATS)
47 } 47 }
@@ -56,7 +56,7 @@ export class VideoViewers {
56 } 56 }
57 57
58 buildViewerExpireTime () { 58 buildViewerExpireTime () {
59 return new Date().getTime() + VIEW_LIFETIME.VIEWER 59 return new Date().getTime() + VIEW_LIFETIME.VIEWER_COUNTER
60 } 60 }
61 61
62 async getWatchTime (videoId: number, ip: string) { 62 async getWatchTime (videoId: number, ip: string) {
@@ -210,7 +210,7 @@ export class VideoViewers {
210 if (this.processingViewerStats) return 210 if (this.processingViewerStats) return
211 this.processingViewerStats = true 211 this.processingViewerStats = true
212 212
213 if (!isTestInstance()) logger.info('Processing viewers.', lTags()) 213 if (!isTestInstance()) logger.info('Processing viewer statistics.', lTags())
214 214
215 const now = new Date().getTime() 215 const now = new Date().getTime()
216 216
@@ -220,6 +220,7 @@ export class VideoViewers {
220 for (const key of allKeys) { 220 for (const key of allKeys) {
221 const stats: LocalViewerStats = await Redis.Instance.getLocalVideoViewer({ key }) 221 const stats: LocalViewerStats = await Redis.Instance.getLocalVideoViewer({ key })
222 222
223 // Process expired stats
223 if (stats.lastUpdated > now - VIEW_LIFETIME.VIEWER_STATS) { 224 if (stats.lastUpdated > now - VIEW_LIFETIME.VIEWER_STATS) {
224 continue 225 continue
225 } 226 }
diff --git a/server/lib/views/video-views-manager.ts b/server/lib/views/video-views-manager.ts
index e07af1ca9..9382fb482 100644
--- a/server/lib/views/video-views-manager.ts
+++ b/server/lib/views/video-views-manager.ts
@@ -3,6 +3,24 @@ import { MVideo } from '@server/types/models'
3import { VideoViewEvent } from '@shared/models' 3import { VideoViewEvent } from '@shared/models'
4import { VideoViewers, VideoViews } from './shared' 4import { VideoViewers, VideoViews } from './shared'
5 5
6/**
7 * If processing a local view:
8 * - We update viewer information (segments watched, watch time etc)
9 * - We add +1 to video viewers counter if this is a new viewer
10 * - We add +1 to video views counter if this is a new view and if the user watched enough seconds
11 * - We send AP message to notify about this viewer and this view
12 * - We update last video time for the user if authenticated
13 *
14 * If processing a remote view:
15 * - We add +1 to video viewers counter
16 * - We add +1 to video views counter
17 *
18 * A viewer is a someone that watched one or multiple sections of a video
19 * A viewer that watched only a few seconds of a video may not increment the video views counter
20 * Viewers statistics are sent to origin instance using the `WatchAction` ActivityPub object
21 *
22 */
23
6const lTags = loggerTagsFactory('views') 24const lTags = loggerTagsFactory('views')
7 25
8export class VideoViewsManager { 26export class VideoViewsManager {
diff --git a/server/models/view/local-video-viewer.ts b/server/models/view/local-video-viewer.ts
index 6f8de53cd..1491acb9e 100644
--- a/server/models/view/local-video-viewer.ts
+++ b/server/models/view/local-video-viewer.ts
@@ -8,6 +8,13 @@ import { AttributesOnly } from '@shared/typescript-utils'
8import { VideoModel } from '../video/video' 8import { VideoModel } from '../video/video'
9import { LocalVideoViewerWatchSectionModel } from './local-video-viewer-watch-section' 9import { LocalVideoViewerWatchSectionModel } from './local-video-viewer-watch-section'
10 10
11/**
12 *
13 * Aggregate viewers of local videos only to display statistics to video owners
14 * A viewer is a user that watched one or multiple sections of a specific video inside a time window
15 *
16 */
17
11@Table({ 18@Table({
12 tableName: 'localVideoViewer', 19 tableName: 'localVideoViewer',
13 updatedAt: false, 20 updatedAt: false,
diff --git a/server/models/view/video-view.ts b/server/models/view/video-view.ts
index df462e631..1504a364e 100644
--- a/server/models/view/video-view.ts
+++ b/server/models/view/video-view.ts
@@ -3,6 +3,13 @@ import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Model, T
3import { AttributesOnly } from '@shared/typescript-utils' 3import { AttributesOnly } from '@shared/typescript-utils'
4import { VideoModel } from '../video/video' 4import { VideoModel } from '../video/video'
5 5
6/**
7 *
8 * Aggregate views of all videos federated with our instance
9 * Mainly used by the trending/hot algorithms
10 *
11 */
12
6@Table({ 13@Table({
7 tableName: 'videoView', 14 tableName: 'videoView',
8 updatedAt: false, 15 updatedAt: false,