1 import * as Sequelize from 'sequelize'
3 import { database as db } from '../../initializers/database'
4 import { AbstractRequestScheduler, RequestsObjects } from './abstract-request-scheduler'
5 import { logger } from '../../helpers'
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'
15 // We create a custom interface because we need "videos" attribute for our computations
16 interface RequestsObjectsCustom<U> extends RequestsObjects<U> {
34 export type RequestVideoQaduSchedulerOptions = {
35 type: RequestVideoQaduType
37 transaction?: Sequelize.Transaction
40 class RequestVideoQaduScheduler extends AbstractRequestScheduler<RequestsVideoQaduGrouped> {
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
48 this.description = 'video QADU requests'
52 return db.RequestVideoQadu
55 getRequestToPodModel () {
56 return db.RequestVideoQadu
59 buildRequestsObjects (requests: RequestsVideoQaduGrouped) {
60 const requestsToMakeGrouped: RequestsObjectsCustom<RemoteQaduVideoRequest> = {}
62 Object.keys(requests).forEach(toPodId => {
63 requests[toPodId].forEach(data => {
64 const request = data.request
65 const video = data.video
67 const hashKey = toPodId
69 if (!requestsToMakeGrouped[hashKey]) {
70 requestsToMakeGrouped[hashKey] = {
72 endpoint: REQUEST_VIDEO_QADU_ENDPOINT,
73 ids: [], // request ids, to delete them from the DB in the future
74 datas: [], // requests data
79 // Maybe another attribute was filled for this video
80 let videoData = requestsToMakeGrouped[hashKey].videos[video.id]
81 if (!videoData) videoData = { remoteId: null }
83 switch (request.type) {
84 case REQUEST_VIDEO_QADU_TYPES.LIKES:
85 videoData.likes = video.likes
88 case REQUEST_VIDEO_QADU_TYPES.DISLIKES:
89 videoData.dislikes = video.dislikes
92 case REQUEST_VIDEO_QADU_TYPES.VIEWS:
93 videoData.views = video.views
97 logger.error('Unknown request video QADU type %s.', request.type)
101 // Do not forget the remoteId so the remote pod can identify the video
102 videoData.remoteId = video.id
103 requestsToMakeGrouped[hashKey].ids.push(request.id)
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
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(videoId => {
114 const videoData = requestsToMakeGrouped[hashKey].videos[videoId]
116 requestsToMakeGrouped[hashKey].datas.push({
121 // We don't need it anymore, it was just to build our datas array
122 delete requestsToMakeGrouped[hashKey].videos
125 return requestsToMakeGrouped
128 createRequest ({ type, videoId, transaction }: RequestVideoQaduSchedulerOptions) {
129 const dbRequestOptions: Sequelize.BulkCreateOptions = {}
130 if (transaction) dbRequestOptions.transaction = transaction
132 // Send the update to all our friends
133 return db.Pod.listAllIds(transaction).then(podIds => {
135 podIds.forEach(podId => {
136 queries.push({ type, videoId, podId })
139 return db.RequestVideoQadu.bulkCreate(queries, dbRequestOptions)
144 // ---------------------------------------------------------------------------
147 RequestVideoQaduScheduler