]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/lib/request/request-video-qadu-scheduler.ts
Use global uuid instead of remoteId for videos
[github/Chocobozzz/PeerTube.git] / server / lib / request / request-video-qadu-scheduler.ts
1 import * as Sequelize from 'sequelize'
2
3 import { database as db } from '../../initializers/database'
4 import { AbstractRequestScheduler, RequestsObjects } from './abstract-request-scheduler'
5 import { logger } from '../../helpers'
6 import {
7 REQUESTS_VIDEO_QADU_LIMIT_PODS,
8 REQUESTS_VIDEO_QADU_LIMIT_PER_POD,
9 REQUEST_VIDEO_QADU_ENDPOINT,
10 REQUEST_VIDEO_QADU_TYPES
11 } from '../../initializers'
12 import { RequestsVideoQaduGrouped, PodInstance } from '../../models'
13 import { RemoteQaduVideoRequest, RequestVideoQaduType } from '../../../shared'
14
15 // We create a custom interface because we need "videos" attribute for our computations
16 interface RequestsObjectsCustom<U> extends RequestsObjects<U> {
17 [ id: string ]: {
18 toPod: PodInstance
19 endpoint: string
20 ids: number[] // ids
21 datas: U[]
22
23 videos: {
24 [ uuid: string ]: {
25 uuid: string
26 likes?: number
27 dislikes?: number
28 views?: number
29 }
30 }
31 }
32 }
33
34 export type RequestVideoQaduSchedulerOptions = {
35 type: RequestVideoQaduType
36 videoId: number
37 transaction?: Sequelize.Transaction
38 }
39
40 class RequestVideoQaduScheduler extends AbstractRequestScheduler<RequestsVideoQaduGrouped> {
41 constructor () {
42 super()
43
44 // We limit the size of the requests
45 this.limitPods = REQUESTS_VIDEO_QADU_LIMIT_PODS
46 this.limitPerPod = REQUESTS_VIDEO_QADU_LIMIT_PER_POD
47
48 this.description = 'video QADU requests'
49 }
50
51 getRequestModel () {
52 return db.RequestVideoQadu
53 }
54
55 getRequestToPodModel () {
56 return db.RequestVideoQadu
57 }
58
59 buildRequestsObjects (requests: RequestsVideoQaduGrouped) {
60 const requestsToMakeGrouped: RequestsObjectsCustom<RemoteQaduVideoRequest> = {}
61
62 Object.keys(requests).forEach(toPodId => {
63 requests[toPodId].forEach(data => {
64 const request = data.request
65 const video = data.video
66 const pod = data.pod
67 const hashKey = toPodId
68
69 if (!requestsToMakeGrouped[hashKey]) {
70 requestsToMakeGrouped[hashKey] = {
71 toPod: pod,
72 endpoint: REQUEST_VIDEO_QADU_ENDPOINT,
73 ids: [], // request ids, to delete them from the DB in the future
74 datas: [], // requests data
75 videos: {}
76 }
77 }
78
79 // Maybe another attribute was filled for this video
80 let videoData = requestsToMakeGrouped[hashKey].videos[video.id]
81 if (!videoData) videoData = { uuid: null }
82
83 switch (request.type) {
84 case REQUEST_VIDEO_QADU_TYPES.LIKES:
85 videoData.likes = video.likes
86 break
87
88 case REQUEST_VIDEO_QADU_TYPES.DISLIKES:
89 videoData.dislikes = video.dislikes
90 break
91
92 case REQUEST_VIDEO_QADU_TYPES.VIEWS:
93 videoData.views = video.views
94 break
95
96 default:
97 logger.error('Unknown request video QADU type %s.', request.type)
98 return
99 }
100
101 // Do not forget the uuid so the remote pod can identify the video
102 videoData.uuid = video.uuid
103 requestsToMakeGrouped[hashKey].ids.push(request.id)
104
105 // Maybe there are multiple quick and dirty update for the same video
106 // We use this hashmap to dedupe them
107 requestsToMakeGrouped[hashKey].videos[video.id] = videoData
108 })
109 })
110
111 // Now we deduped similar quick and dirty updates, we can build our requests datas
112 Object.keys(requestsToMakeGrouped).forEach(hashKey => {
113 Object.keys(requestsToMakeGrouped[hashKey].videos).forEach(videoUUID => {
114 const videoData = requestsToMakeGrouped[hashKey].videos[videoUUID]
115
116 requestsToMakeGrouped[hashKey].datas.push({
117 data: videoData
118 })
119 })
120
121 // We don't need it anymore, it was just to build our datas array
122 delete requestsToMakeGrouped[hashKey].videos
123 })
124
125 return requestsToMakeGrouped
126 }
127
128 createRequest ({ type, videoId, transaction }: RequestVideoQaduSchedulerOptions) {
129 const dbRequestOptions: Sequelize.BulkCreateOptions = {}
130 if (transaction) dbRequestOptions.transaction = transaction
131
132 // Send the update to all our friends
133 return db.Pod.listAllIds(transaction).then(podIds => {
134 const queries = []
135 podIds.forEach(podId => {
136 queries.push({ type, videoId, podId })
137 })
138
139 return db.RequestVideoQadu.bulkCreate(queries, dbRequestOptions)
140 })
141 }
142 }
143
144 // ---------------------------------------------------------------------------
145
146 export {
147 RequestVideoQaduScheduler
148 }