@@ -14,49 +14,57 @@ type AdditionalDetails = {
14
14
thumbnail : { [ key : number ] : [ ] }
15
15
prefetch : { [ key : number ] : [ ] }
16
16
}
17
-
17
+
18
18
class RequestPoolManager {
19
19
// priority is fixed for interaction and thumbnail to be 0, however,
20
20
// the priority of prefetch can be configured and it can have priorities other
21
21
// than 0 (highest priority)
22
-
22
+
23
23
// TODO: Some of this stuff shouldn't be public but it's easier right now
24
24
private requestPool : RequestPool ;
25
25
private awake : boolean ;
26
- private numRequests : { interaction : number , thumbnail : number , prefetch : number } ;
27
- public maxNumRequests : { interaction : number , thumbnail : number , prefetch : number } ;
26
+ private numRequests : {
27
+ interaction : number ;
28
+ thumbnail : number ;
29
+ prefetch : number ;
30
+ } ;
31
+ public maxNumRequests : {
32
+ interaction : number ;
33
+ thumbnail : number ;
34
+ prefetch : number ;
35
+ } ;
28
36
public grabDelay : number ;
29
37
private timeoutHandle : number ;
30
-
38
+
31
39
constructor ( ) {
32
40
this . requestPool = {
33
41
interaction : { 0 : [ ] } ,
34
42
thumbnail : { 0 : [ ] } ,
35
43
prefetch : { 0 : [ ] } ,
36
- }
37
-
44
+ } ;
45
+
38
46
this . awake = false ;
39
47
this . grabDelay = 5 ;
40
-
41
- this . numRequests = {
48
+
49
+ this . numRequests = {
42
50
interaction : 0 ,
43
51
thumbnail : 0 ,
44
52
prefetch : 0 ,
45
53
} ;
46
-
54
+
47
55
this . maxNumRequests = {
48
56
interaction : 6 ,
49
57
thumbnail : 6 ,
50
58
prefetch : 5 ,
51
- }
59
+ } ;
52
60
}
53
-
61
+
54
62
destroy ( ) {
55
63
if ( this . timeoutHandle ) {
56
- window . clearTimeout ( this . timeoutHandle )
64
+ window . clearTimeout ( this . timeoutHandle ) ;
57
65
}
58
66
}
59
-
67
+
60
68
/**
61
69
* Adds the requests to the pool of requests.
62
70
*
@@ -75,30 +83,37 @@ type AdditionalDetails = {
75
83
requestFn : ( ) => Promise < void > ,
76
84
type : string ,
77
85
additionalDetails : Record < string , unknown > ,
78
- priority = 0
86
+ priority = 0 ,
87
+ addToBeginning = false
79
88
) : void {
80
89
// Describe the request
81
90
const requestDetails : RequestDetailsInterface = {
82
91
requestFn,
83
92
type,
84
93
additionalDetails,
85
- }
86
-
94
+ } ;
95
+
87
96
// Check if the priority group exists on the request type
88
97
if ( this . requestPool [ type ] [ priority ] === undefined ) {
89
- this . requestPool [ type ] [ priority ] = [ ]
98
+ this . requestPool [ type ] [ priority ] = [ ] ;
90
99
}
91
-
100
+
92
101
// Adding the request to the correct priority group of the request type
93
- this . requestPool [ type ] [ priority ] . push ( requestDetails )
94
-
102
+ if ( addToBeginning ) {
103
+ // Add it to the beginning of the stack
104
+ this . requestPool [ type ] [ priority ] . unshift ( requestDetails ) ;
105
+ } else {
106
+ // Add it to the end of the stack
107
+ this . requestPool [ type ] [ priority ] . push ( requestDetails ) ;
108
+ }
109
+
95
110
// Wake up
96
111
if ( ! this . awake ) {
97
- this . awake = true
98
- this . startGrabbing ( )
112
+ this . awake = true ;
113
+ this . startGrabbing ( ) ;
99
114
}
100
115
}
101
-
116
+
102
117
/**
103
118
* Filter the requestPoolManager's pool of request based on the result of
104
119
* provided filter function. The provided filter function needs to return false or true
@@ -110,17 +125,17 @@ type AdditionalDetails = {
110
125
filterFunction : ( requestDetails : RequestDetailsInterface ) => boolean
111
126
) : void {
112
127
Object . keys ( this . requestPool ) . forEach ( ( type : string ) => {
113
- const requestType = this . requestPool [ type ]
128
+ const requestType = this . requestPool [ type ] ;
114
129
Object . keys ( requestType ) . forEach ( ( priority ) => {
115
130
requestType [ priority ] = requestType [ priority ] . filter (
116
131
( requestDetails : RequestDetailsInterface ) => {
117
- return filterFunction ( requestDetails )
132
+ return filterFunction ( requestDetails ) ;
118
133
}
119
- )
120
- } )
121
- } )
134
+ ) ;
135
+ } ) ;
136
+ } ) ;
122
137
}
123
-
138
+
124
139
/**
125
140
* Clears the requests specific to the provided type. For instance, the
126
141
* pool of requests of type 'interaction' can be cleared via this function.
@@ -131,110 +146,114 @@ type AdditionalDetails = {
131
146
*/
132
147
clearRequestStack ( type : string ) : void {
133
148
if ( ! this . requestPool [ type ] ) {
134
- throw new Error ( `No category for the type ${ type } found` )
149
+ throw new Error ( `No category for the type ${ type } found` ) ;
135
150
}
136
- this . requestPool [ type ] = { 0 : [ ] }
151
+ this . requestPool [ type ] = { 0 : [ ] } ;
137
152
}
138
-
153
+
139
154
sendRequest ( { requestFn, type } : RequestDetailsInterface ) {
140
155
// Increment the number of current requests of this type
141
- this . numRequests [ type ] ++
142
- this . awake = true
143
-
156
+ this . numRequests [ type ] ++ ;
157
+ this . awake = true ;
158
+
144
159
requestFn ( ) . finally ( ( ) => {
145
- this . numRequests [ type ] --
146
-
147
- this . startAgain ( )
148
- } )
160
+ this . numRequests [ type ] -- ;
161
+
162
+ this . startAgain ( ) ;
163
+ } ) ;
149
164
}
150
-
165
+
151
166
startGrabbing ( ) : void {
152
167
// Begin by grabbing X images
153
-
168
+
154
169
// TODO: This is the reason things aren't going as fast as expected
155
170
// const maxSimultaneousRequests = getMaxSimultaneousRequests()
156
171
// this.maxNumRequests = {
157
172
// interaction: Math.max(maxSimultaneousRequests, 1),
158
173
// thumbnail: Math.max(maxSimultaneousRequests - 2, 1),
159
174
// prefetch: Math.max(maxSimultaneousRequests - 1, 1),
160
175
// }
161
-
176
+
162
177
const maxRequests =
163
- this . maxNumRequests . interaction + this . maxNumRequests . thumbnail + this . maxNumRequests . prefetch
178
+ this . maxNumRequests . interaction +
179
+ this . maxNumRequests . thumbnail +
180
+ this . maxNumRequests . prefetch ;
164
181
const currentRequests =
165
- this . numRequests . interaction + this . numRequests . thumbnail + this . numRequests . prefetch
166
- const requestsToSend = maxRequests - currentRequests
182
+ this . numRequests . interaction +
183
+ this . numRequests . thumbnail +
184
+ this . numRequests . prefetch ;
185
+ const requestsToSend = maxRequests - currentRequests ;
167
186
for ( let i = 0 ; i < requestsToSend ; i ++ ) {
168
- const requestDetails = this . getNextRequest ( )
187
+ const requestDetails = this . getNextRequest ( ) ;
169
188
if ( requestDetails === false ) {
170
189
break ;
171
190
} else if ( requestDetails ) {
172
- this . sendRequest ( requestDetails )
191
+ this . sendRequest ( requestDetails ) ;
173
192
}
174
193
}
175
194
}
176
-
195
+
177
196
startAgain ( ) : void {
178
197
if ( ! this . awake ) {
179
- return
198
+ return ;
180
199
}
181
-
200
+
182
201
if ( this . grabDelay ) {
183
202
this . timeoutHandle = window . setTimeout ( ( ) => {
184
- this . startGrabbing ( )
185
- } , this . grabDelay )
203
+ this . startGrabbing ( ) ;
204
+ } , this . grabDelay ) ;
186
205
} else {
187
- this . startGrabbing ( )
206
+ this . startGrabbing ( ) ;
188
207
}
189
208
}
190
-
209
+
191
210
getSortedPriorityGroups ( type : string ) : Array < number > {
192
211
const priorities = Object . keys ( this . requestPool [ type ] )
193
212
. map ( Number )
194
213
. filter ( ( priority ) => this . requestPool [ type ] [ priority ] . length )
195
- . sort ( )
196
- return priorities
214
+ . sort ( ) ;
215
+ return priorities ;
197
216
}
198
-
217
+
199
218
getNextRequest ( ) : RequestDetailsInterface | false {
200
- const interactionPriorities = this . getSortedPriorityGroups ( 'interaction' )
219
+ const interactionPriorities = this . getSortedPriorityGroups ( 'interaction' ) ;
201
220
for ( const priority of interactionPriorities ) {
202
221
if (
203
222
this . requestPool . interaction [ priority ] . length &&
204
223
this . numRequests . interaction < this . maxNumRequests . interaction
205
224
) {
206
- return this . requestPool . interaction [ priority ] . shift ( )
225
+ return this . requestPool . interaction [ priority ] . shift ( ) ;
207
226
}
208
227
}
209
- const thumbnailPriorities = this . getSortedPriorityGroups ( 'thumbnail' )
228
+ const thumbnailPriorities = this . getSortedPriorityGroups ( 'thumbnail' ) ;
210
229
for ( const priority of thumbnailPriorities ) {
211
230
if (
212
231
this . requestPool . thumbnail [ priority ] . length &&
213
232
this . numRequests . thumbnail < this . maxNumRequests . thumbnail
214
233
) {
215
- return this . requestPool . thumbnail [ priority ] . shift ( )
234
+ return this . requestPool . thumbnail [ priority ] . shift ( ) ;
216
235
}
217
236
}
218
- const prefetchPriorities = this . getSortedPriorityGroups ( 'prefetch' )
237
+ const prefetchPriorities = this . getSortedPriorityGroups ( 'prefetch' ) ;
219
238
for ( const priority of prefetchPriorities ) {
220
239
if (
221
240
this . requestPool . prefetch [ priority ] . length &&
222
241
this . numRequests . prefetch < this . maxNumRequests . prefetch
223
242
) {
224
- return this . requestPool . prefetch [ priority ] . shift ( )
243
+ return this . requestPool . prefetch [ priority ] . shift ( ) ;
225
244
}
226
245
}
227
-
246
+
228
247
if (
229
248
! interactionPriorities . length &&
230
249
! thumbnailPriorities . length &&
231
250
! prefetchPriorities . length
232
251
) {
233
- this . awake = false
252
+ this . awake = false ;
234
253
}
235
- return false
254
+ return false ;
236
255
}
237
-
256
+
238
257
/**
239
258
* Returns the request pool containing different categories, their priority and
240
259
* the added request details.
@@ -243,7 +262,7 @@ type AdditionalDetails = {
243
262
* @category requestPool
244
263
*/
245
264
getRequestPool ( ) : RequestPool {
246
- return this . requestPool
265
+ return this . requestPool ;
247
266
}
248
267
}
249
268
0 commit comments