c3f7f6429aebb490b882f7db575e55338610a976
[oweals/peertube.git] / server / lib / request / request-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 { REQUESTS_LIMIT_PODS, REQUESTS_LIMIT_PER_POD } from '../../initializers'
7 import { RequestsGrouped } from '../../models'
8 import { RequestEndpoint, RemoteVideoRequest } from '../../../shared'
9
10 export type RequestSchedulerOptions = {
11   type: string
12   endpoint: RequestEndpoint
13   data: Object
14   toIds: number[]
15   transaction: Sequelize.Transaction
16 }
17
18 class RequestScheduler extends AbstractRequestScheduler<RequestsGrouped> {
19   constructor () {
20     super()
21
22     // We limit the size of the requests
23     this.limitPods = REQUESTS_LIMIT_PODS
24     this.limitPerPod = REQUESTS_LIMIT_PER_POD
25
26     this.description = 'requests'
27   }
28
29   getRequestModel () {
30     return db.Request
31   }
32
33   getRequestToPodModel () {
34     return db.RequestToPod
35   }
36
37   buildRequestsObjects (requestsGrouped: RequestsGrouped) {
38     const requestsToMakeGrouped: RequestsObjects<RemoteVideoRequest> = {}
39
40     for (const toPodId of Object.keys(requestsGrouped)) {
41       for (const data of requestsGrouped[toPodId]) {
42         const request = data.request
43         const pod = data.pod
44         const hashKey = toPodId + request.endpoint
45
46         if (!requestsToMakeGrouped[hashKey]) {
47           requestsToMakeGrouped[hashKey] = {
48             toPod: pod,
49             endpoint: request.endpoint,
50             ids: [], // request ids, to delete them from the DB in the future
51             datas: [] // requests data,
52           }
53         }
54
55         requestsToMakeGrouped[hashKey].ids.push(request.id)
56         requestsToMakeGrouped[hashKey].datas.push(request.request)
57       }
58     }
59
60     return requestsToMakeGrouped
61   }
62
63   async createRequest ({ type, endpoint, data, toIds, transaction }: RequestSchedulerOptions) {
64     // If there are no destination pods abort
65     if (toIds.length === 0) return undefined
66
67     const createQuery = {
68       endpoint,
69       request: {
70         type: type,
71         data: data
72       }
73     }
74
75     const dbRequestOptions: Sequelize.CreateOptions = {
76       transaction
77     }
78
79     const request = await db.Request.create(createQuery, dbRequestOptions)
80     await request.setPods(toIds, dbRequestOptions)
81   }
82
83   // ---------------------------------------------------------------------------
84
85   afterRequestsHook () {
86     // Flush requests with no pod
87     this.getRequestModel().removeWithEmptyTo()
88       .catch(err => logger.error('Error when removing requests with no pods.', err))
89   }
90 }
91
92 // ---------------------------------------------------------------------------
93
94 export {
95   RequestScheduler
96 }