From 51353d9a035fb6b81f903a8b5f391292841649fd Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 9 Nov 2021 10:11:20 +0100 Subject: Refactor video views Introduce viewers attribute for live videos Count views for live videos Reduce delay to see the viewer update for lives Add ability to configure video views buffer interval and view ip expiration --- server/controllers/api/videos/index.ts | 44 +++++++--------------------------- 1 file changed, 8 insertions(+), 36 deletions(-) (limited to 'server/controllers') diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts index 821161c64..72b382595 100644 --- a/server/controllers/api/videos/index.ts +++ b/server/controllers/api/videos/index.ts @@ -2,7 +2,7 @@ import express from 'express' import toInt from 'validator/lib/toInt' import { pickCommonVideoQuery } from '@server/helpers/query' import { doJSONRequest } from '@server/helpers/requests' -import { LiveManager } from '@server/lib/live' +import { VideoViews } from '@server/lib/video-views' import { openapiOperationDoc } from '@server/middlewares/doc' import { getServerActor } from '@server/models/application/application' import { guessAdditionalAttributesFromQuery } from '@server/models/video/formatter/video-format-utils' @@ -17,7 +17,6 @@ import { sequelizeTypescript } from '../../../initializers/database' import { sendView } from '../../../lib/activitypub/send/send-view' import { JobQueue } from '../../../lib/job-queue' import { Hooks } from '../../../lib/plugins/hooks' -import { Redis } from '../../../lib/redis' import { asyncMiddleware, asyncRetryTransactionMiddleware, @@ -107,7 +106,7 @@ videosRouter.get('/:id', ) videosRouter.post('/:id/views', openapiOperationDoc({ operationId: 'addView' }), - asyncMiddleware(videosCustomGetValidator('only-immutable-attributes')), + asyncMiddleware(videosCustomGetValidator('only-video')), asyncMiddleware(viewVideo) ) @@ -153,44 +152,17 @@ function getVideo (_req: express.Request, res: express.Response) { } async function viewVideo (req: express.Request, res: express.Response) { - const immutableVideoAttrs = res.locals.onlyImmutableVideo + const video = res.locals.onlyVideo const ip = req.ip - const exists = await Redis.Instance.doesVideoIPViewExist(ip, immutableVideoAttrs.uuid) - if (exists) { - logger.debug('View for ip %s and video %s already exists.', ip, immutableVideoAttrs.uuid) - return res.status(HttpStatusCode.NO_CONTENT_204).end() - } - - const video = await VideoModel.load(immutableVideoAttrs.id) - - const promises: Promise[] = [ - Redis.Instance.setIPVideoView(ip, video.uuid, video.isLive) - ] - - let federateView = true - - // Increment our live manager - if (video.isLive && video.isOwned()) { - LiveManager.Instance.addViewTo(video.id) - - // Views of our local live will be sent by our live manager - federateView = false - } - - // Increment our video views cache counter - if (!video.isLive) { - promises.push(Redis.Instance.addVideoView(video.id)) - } + const success = await VideoViews.Instance.processView({ video, ip }) - if (federateView) { + if (success) { const serverActor = await getServerActor() - promises.push(sendView(serverActor, video, undefined)) - } - - await Promise.all(promises) + await sendView(serverActor, video, undefined) - Hooks.runAction('action:api.video.viewed', { video, ip }) + Hooks.runAction('action:api.video.viewed', { video: video, ip }) + } return res.status(HttpStatusCode.NO_CONTENT_204).end() } -- cgit v1.2.3