diff options
Diffstat (limited to 'server/lib/request/abstract-request-scheduler.ts')
-rw-r--r-- | server/lib/request/abstract-request-scheduler.ts | 168 |
1 files changed, 0 insertions, 168 deletions
diff --git a/server/lib/request/abstract-request-scheduler.ts b/server/lib/request/abstract-request-scheduler.ts deleted file mode 100644 index f838c47f2..000000000 --- a/server/lib/request/abstract-request-scheduler.ts +++ /dev/null | |||
@@ -1,168 +0,0 @@ | |||
1 | import { isEmpty } from 'lodash' | ||
2 | import * as Bluebird from 'bluebird' | ||
3 | |||
4 | import { database as db } from '../../initializers/database' | ||
5 | import { logger, makeSecureRequest } from '../../helpers' | ||
6 | import { AbstractRequestClass, AbstractRequestToPodClass, PodInstance } from '../../models' | ||
7 | import { | ||
8 | API_VERSION, | ||
9 | REQUESTS_IN_PARALLEL, | ||
10 | REQUESTS_INTERVAL | ||
11 | } from '../../initializers' | ||
12 | |||
13 | interface RequestsObjects<U> { | ||
14 | [ id: string ]: { | ||
15 | toPod: PodInstance | ||
16 | endpoint: string | ||
17 | ids: number[] // ids | ||
18 | datas: U[] | ||
19 | } | ||
20 | } | ||
21 | |||
22 | abstract class AbstractRequestScheduler <T> { | ||
23 | requestInterval: number | ||
24 | limitPods: number | ||
25 | limitPerPod: number | ||
26 | |||
27 | protected lastRequestTimestamp: number | ||
28 | protected timer: NodeJS.Timer | ||
29 | protected description: string | ||
30 | |||
31 | constructor () { | ||
32 | this.lastRequestTimestamp = 0 | ||
33 | this.timer = null | ||
34 | this.requestInterval = REQUESTS_INTERVAL | ||
35 | } | ||
36 | |||
37 | abstract getRequestModel (): AbstractRequestClass<T> | ||
38 | abstract getRequestToPodModel (): AbstractRequestToPodClass | ||
39 | abstract buildRequestsObjects (requestsGrouped: T): RequestsObjects<any> | ||
40 | |||
41 | activate () { | ||
42 | logger.info('Requests scheduler activated.') | ||
43 | this.lastRequestTimestamp = Date.now() | ||
44 | |||
45 | this.timer = setInterval(() => { | ||
46 | this.lastRequestTimestamp = Date.now() | ||
47 | this.makeRequests() | ||
48 | }, this.requestInterval) | ||
49 | } | ||
50 | |||
51 | deactivate () { | ||
52 | logger.info('Requests scheduler deactivated.') | ||
53 | clearInterval(this.timer) | ||
54 | this.timer = null | ||
55 | } | ||
56 | |||
57 | forceSend () { | ||
58 | logger.info('Force requests scheduler sending.') | ||
59 | this.makeRequests() | ||
60 | } | ||
61 | |||
62 | remainingMilliSeconds () { | ||
63 | if (this.timer === null) return -1 | ||
64 | |||
65 | return REQUESTS_INTERVAL - (Date.now() - this.lastRequestTimestamp) | ||
66 | } | ||
67 | |||
68 | remainingRequestsCount () { | ||
69 | return this.getRequestModel().countTotalRequests() | ||
70 | } | ||
71 | |||
72 | flush () { | ||
73 | return this.getRequestModel().removeAll() | ||
74 | } | ||
75 | |||
76 | // --------------------------------------------------------------------------- | ||
77 | |||
78 | // Make a requests to friends of a certain type | ||
79 | protected async makeRequest (toPod: PodInstance, requestEndpoint: string, requestsToMake: any) { | ||
80 | const params = { | ||
81 | toPod: toPod, | ||
82 | method: 'POST' as 'POST', | ||
83 | path: '/api/' + API_VERSION + '/remote/' + requestEndpoint, | ||
84 | data: requestsToMake // Requests we need to make | ||
85 | } | ||
86 | |||
87 | // Make multiple retry requests to all of pods | ||
88 | // The function fire some useful callbacks | ||
89 | try { | ||
90 | const { response } = await makeSecureRequest(params) | ||
91 | |||
92 | // 400 because if the other pod is not up to date, it may not understand our request | ||
93 | if ([ 200, 201, 204, 400 ].indexOf(response.statusCode) === -1) { | ||
94 | throw new Error('Status code not 20x or 400 : ' + response.statusCode) | ||
95 | } | ||
96 | } catch (err) { | ||
97 | logger.error('Error sending secure request to %s pod.', toPod.host, err) | ||
98 | |||
99 | throw err | ||
100 | } | ||
101 | } | ||
102 | |||
103 | // Make all the requests of the scheduler | ||
104 | protected async makeRequests () { | ||
105 | let requestsGrouped: T | ||
106 | |||
107 | try { | ||
108 | requestsGrouped = await this.getRequestModel().listWithLimitAndRandom(this.limitPods, this.limitPerPod) | ||
109 | } catch (err) { | ||
110 | logger.error('Cannot get the list of "%s".', this.description, { error: err.stack }) | ||
111 | throw err | ||
112 | } | ||
113 | |||
114 | // We want to group requests by destinations pod and endpoint | ||
115 | const requestsToMake = this.buildRequestsObjects(requestsGrouped) | ||
116 | |||
117 | // If there are no requests, abort | ||
118 | if (isEmpty(requestsToMake) === true) { | ||
119 | logger.info('No "%s" to make.', this.description) | ||
120 | return { goodPods: [], badPods: [] } | ||
121 | } | ||
122 | |||
123 | logger.info('Making "%s" to friends.', this.description) | ||
124 | |||
125 | const goodPods: number[] = [] | ||
126 | const badPods: number[] = [] | ||
127 | |||
128 | await Bluebird.map(Object.keys(requestsToMake), async hashKey => { | ||
129 | const requestToMake = requestsToMake[hashKey] | ||
130 | const toPod: PodInstance = requestToMake.toPod | ||
131 | |||
132 | try { | ||
133 | await this.makeRequest(toPod, requestToMake.endpoint, requestToMake.datas) | ||
134 | logger.debug('Removing requests for pod %s.', requestToMake.toPod.id, { requestsIds: requestToMake.ids }) | ||
135 | goodPods.push(requestToMake.toPod.id) | ||
136 | |||
137 | this.afterRequestHook() | ||
138 | |||
139 | // Remove the pod id of these request ids | ||
140 | await this.getRequestToPodModel() | ||
141 | .removeByRequestIdsAndPod(requestToMake.ids, requestToMake.toPod.id) | ||
142 | } catch (err) { | ||
143 | badPods.push(requestToMake.toPod.id) | ||
144 | logger.info('Cannot make request to %s.', toPod.host, err) | ||
145 | } | ||
146 | }, { concurrency: REQUESTS_IN_PARALLEL }) | ||
147 | |||
148 | this.afterRequestsHook() | ||
149 | |||
150 | // All the requests were made, we update the pods score | ||
151 | db.Pod.updatePodsScore(goodPods, badPods) | ||
152 | } | ||
153 | |||
154 | protected afterRequestHook () { | ||
155 | // Nothing to do, let children re-implement it | ||
156 | } | ||
157 | |||
158 | protected afterRequestsHook () { | ||
159 | // Nothing to do, let children re-implement it | ||
160 | } | ||
161 | } | ||
162 | |||
163 | // --------------------------------------------------------------------------- | ||
164 | |||
165 | export { | ||
166 | AbstractRequestScheduler, | ||
167 | RequestsObjects | ||
168 | } | ||