Improve views/viewers documentation

pull/4903/head
Chocobozzz 2022-04-05 15:15:09 +02:00 committed by Chocobozzz
parent d74bb0647c
commit dfbcefc20d
6 changed files with 39 additions and 6 deletions

View File

@ -367,7 +367,7 @@ const CONSTRAINTS_FIELDS = {
const VIEW_LIFETIME = {
VIEW: CONFIG.VIEWS.VIDEOS.IP_VIEW_EXPIRATION,
VIEWER: 60000 * 5, // 5 minutes
VIEWER_COUNTER: 60000 * 5, // 5 minutes
VIEWER_STATS: 60000 * 60 // 1 hour
}
@ -845,7 +845,7 @@ if (isTestInstance() === true) {
REDUNDANCY.VIDEOS.RANDOMIZED_FACTOR = 1
VIEW_LIFETIME.VIEWER = 1000 * 5 // 5 second
VIEW_LIFETIME.VIEWER_COUNTER = 1000 * 5 // 5 second
VIEW_LIFETIME.VIEWER_STATS = 1000 * 5 // 5 second
CONTACT_FORM_LIFETIME = 1000 // 1 second

View File

@ -146,7 +146,7 @@ class Redis {
}
setIPVideoViewer (ip: string, videoUUID: string) {
return this.setValue(this.generateIPViewerKey(ip, videoUUID), '1', VIEW_LIFETIME.VIEWER)
return this.setValue(this.generateIPViewerKey(ip, videoUUID), '1', VIEW_LIFETIME.VIEWER_COUNTER)
}
async doesVideoIPViewExist (ip: string, videoUUID: string) {

View File

@ -41,7 +41,7 @@ export class VideoViewers {
private processingViewerStats = false
constructor () {
setInterval(() => this.cleanViewerCounters(), VIEW_LIFETIME.VIEWER)
setInterval(() => this.cleanViewerCounters(), VIEW_LIFETIME.VIEWER_COUNTER)
setInterval(() => this.processViewerStats(), VIEW_LIFETIME.VIEWER_STATS)
}
@ -56,7 +56,7 @@ export class VideoViewers {
}
buildViewerExpireTime () {
return new Date().getTime() + VIEW_LIFETIME.VIEWER
return new Date().getTime() + VIEW_LIFETIME.VIEWER_COUNTER
}
async getWatchTime (videoId: number, ip: string) {
@ -210,7 +210,7 @@ export class VideoViewers {
if (this.processingViewerStats) return
this.processingViewerStats = true
if (!isTestInstance()) logger.info('Processing viewers.', lTags())
if (!isTestInstance()) logger.info('Processing viewer statistics.', lTags())
const now = new Date().getTime()
@ -220,6 +220,7 @@ export class VideoViewers {
for (const key of allKeys) {
const stats: LocalViewerStats = await Redis.Instance.getLocalVideoViewer({ key })
// Process expired stats
if (stats.lastUpdated > now - VIEW_LIFETIME.VIEWER_STATS) {
continue
}

View File

@ -3,6 +3,24 @@ import { MVideo } from '@server/types/models'
import { VideoViewEvent } from '@shared/models'
import { VideoViewers, VideoViews } from './shared'
/**
* If processing a local view:
* - We update viewer information (segments watched, watch time etc)
* - We add +1 to video viewers counter if this is a new viewer
* - We add +1 to video views counter if this is a new view and if the user watched enough seconds
* - We send AP message to notify about this viewer and this view
* - We update last video time for the user if authenticated
*
* If processing a remote view:
* - We add +1 to video viewers counter
* - We add +1 to video views counter
*
* A viewer is a someone that watched one or multiple sections of a video
* A viewer that watched only a few seconds of a video may not increment the video views counter
* Viewers statistics are sent to origin instance using the `WatchAction` ActivityPub object
*
*/
const lTags = loggerTagsFactory('views')
export class VideoViewsManager {

View File

@ -8,6 +8,13 @@ import { AttributesOnly } from '@shared/typescript-utils'
import { VideoModel } from '../video/video'
import { LocalVideoViewerWatchSectionModel } from './local-video-viewer-watch-section'
/**
*
* Aggregate viewers of local videos only to display statistics to video owners
* A viewer is a user that watched one or multiple sections of a specific video inside a time window
*
*/
@Table({
tableName: 'localVideoViewer',
updatedAt: false,

View File

@ -3,6 +3,13 @@ import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Model, T
import { AttributesOnly } from '@shared/typescript-utils'
import { VideoModel } from '../video/video'
/**
*
* Aggregate views of all videos federated with our instance
* Mainly used by the trending/hot algorithms
*
*/
@Table({
tableName: 'videoView',
updatedAt: false,