149 lines
4.4 KiB
TypeScript
149 lines
4.4 KiB
TypeScript
import * as Sequelize from 'sequelize'
|
|
|
|
import { database as db } from '../../initializers/database'
|
|
import { AbstractRequestScheduler, RequestsObjects } from './abstract-request-scheduler'
|
|
import { logger } from '../../helpers'
|
|
import {
|
|
REQUESTS_VIDEO_QADU_LIMIT_PODS,
|
|
REQUESTS_VIDEO_QADU_LIMIT_PER_POD,
|
|
REQUEST_VIDEO_QADU_ENDPOINT,
|
|
REQUEST_VIDEO_QADU_TYPES
|
|
} from '../../initializers'
|
|
import { RequestsVideoQaduGrouped, PodInstance } from '../../models'
|
|
import { RemoteQaduVideoRequest, RequestVideoQaduType } from '../../../shared'
|
|
|
|
// We create a custom interface because we need "videos" attribute for our computations
|
|
interface RequestsObjectsCustom<U> extends RequestsObjects<U> {
|
|
[ id: string ]: {
|
|
toPod: PodInstance
|
|
endpoint: string
|
|
ids: number[] // ids
|
|
datas: U[]
|
|
|
|
videos: {
|
|
[ uuid: string ]: {
|
|
uuid: string
|
|
likes?: number
|
|
dislikes?: number
|
|
views?: number
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export type RequestVideoQaduSchedulerOptions = {
|
|
type: RequestVideoQaduType
|
|
videoId: number
|
|
transaction?: Sequelize.Transaction
|
|
}
|
|
|
|
class RequestVideoQaduScheduler extends AbstractRequestScheduler<RequestsVideoQaduGrouped> {
|
|
constructor () {
|
|
super()
|
|
|
|
// We limit the size of the requests
|
|
this.limitPods = REQUESTS_VIDEO_QADU_LIMIT_PODS
|
|
this.limitPerPod = REQUESTS_VIDEO_QADU_LIMIT_PER_POD
|
|
|
|
this.description = 'video QADU requests'
|
|
}
|
|
|
|
getRequestModel () {
|
|
return db.RequestVideoQadu
|
|
}
|
|
|
|
getRequestToPodModel () {
|
|
return db.RequestVideoQadu
|
|
}
|
|
|
|
buildRequestsObjects (requests: RequestsVideoQaduGrouped) {
|
|
const requestsToMakeGrouped: RequestsObjectsCustom<RemoteQaduVideoRequest> = {}
|
|
|
|
for (const toPodId of Object.keys(requests)) {
|
|
for (const data of requests[toPodId]) {
|
|
const request = data.request
|
|
const video = data.video
|
|
const pod = data.pod
|
|
const hashKey = toPodId
|
|
|
|
if (!requestsToMakeGrouped[hashKey]) {
|
|
requestsToMakeGrouped[hashKey] = {
|
|
toPod: pod,
|
|
endpoint: REQUEST_VIDEO_QADU_ENDPOINT,
|
|
ids: [], // request ids, to delete them from the DB in the future
|
|
datas: [], // requests data
|
|
videos: {}
|
|
}
|
|
}
|
|
|
|
// Maybe another attribute was filled for this video
|
|
let videoData = requestsToMakeGrouped[hashKey].videos[video.id]
|
|
if (!videoData) videoData = { uuid: null }
|
|
|
|
switch (request.type) {
|
|
case REQUEST_VIDEO_QADU_TYPES.LIKES:
|
|
videoData.likes = video.likes
|
|
break
|
|
|
|
case REQUEST_VIDEO_QADU_TYPES.DISLIKES:
|
|
videoData.dislikes = video.dislikes
|
|
break
|
|
|
|
case REQUEST_VIDEO_QADU_TYPES.VIEWS:
|
|
videoData.views = video.views
|
|
break
|
|
|
|
default:
|
|
logger.error('Unknown request video QADU type %s.', request.type)
|
|
return undefined
|
|
}
|
|
|
|
// Do not forget the uuid so the remote pod can identify the video
|
|
videoData.uuid = video.uuid
|
|
requestsToMakeGrouped[hashKey].ids.push(request.id)
|
|
|
|
// Maybe there are multiple quick and dirty update for the same video
|
|
// We use this hash map to dedupe them
|
|
requestsToMakeGrouped[hashKey].videos[video.id] = videoData
|
|
}
|
|
}
|
|
|
|
// Now we deduped similar quick and dirty updates, we can build our requests data
|
|
for (const hashKey of Object.keys(requestsToMakeGrouped)) {
|
|
for (const videoUUID of Object.keys(requestsToMakeGrouped[hashKey].videos)) {
|
|
const videoData = requestsToMakeGrouped[hashKey].videos[videoUUID]
|
|
|
|
requestsToMakeGrouped[hashKey].datas.push({
|
|
data: videoData
|
|
})
|
|
}
|
|
|
|
// We don't need it anymore, it was just to build our data array
|
|
delete requestsToMakeGrouped[hashKey].videos
|
|
}
|
|
|
|
return requestsToMakeGrouped
|
|
}
|
|
|
|
async createRequest ({ type, videoId, transaction }: RequestVideoQaduSchedulerOptions) {
|
|
const dbRequestOptions: Sequelize.BulkCreateOptions = {}
|
|
if (transaction) dbRequestOptions.transaction = transaction
|
|
|
|
// Send the update to all our friends
|
|
const podIds = await db.Pod.listAllIds(transaction)
|
|
const queries = []
|
|
for (const podId of podIds) {
|
|
queries.push({ type, videoId, podId })
|
|
}
|
|
|
|
await db.RequestVideoQadu.bulkCreate(queries, dbRequestOptions)
|
|
return undefined
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export {
|
|
RequestVideoQaduScheduler
|
|
}
|