This repository was archived by the owner on Dec 29, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy paththrottler.dart
79 lines (67 loc) · 2.02 KB
/
throttler.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import '../../elements.dart';
class _RequestInfo {
final void Function(Operation) start;
final Operation onDone;
final Zone zone;
final Priority priority;
final int requestNumber;
_RequestInfo(this.start, this.onDone, this.zone, this.priority, this.requestNumber);
String toString() => 'Request #$requestNumber $priority';
}
class RequestThrotller {
int maxRequests;
bool logRequests;
List<List<_RequestInfo>> requestQueues = [];
int nextRequestNumber = 0;
int requestsInFlight = 0;
RequestThrotller(this.maxRequests, this.logRequests) {
for (int i = 0; i < Priority.values.length; ++i) {
requestQueues.add([]);
}
}
void addRequest(_RequestInfo request) {
requestQueues[request.priority.index].add(request);
}
_RequestInfo nextRequest() {
for (int i = 0; i < Priority.values.length; ++i) {
if (requestQueues[i].isNotEmpty) {
return requestQueues[i].removeAt(0);
}
}
return null;
}
void schedule(void Function(Operation) start, Operation onDone, Zone zone, Priority priority) {
_RequestInfo request = _RequestInfo(start, onDone, zone, priority, nextRequestNumber++);
if (logRequests) {
print('Scheduled $request');
}
addRequest(request);
processPendingRequests();
}
void processPendingRequests() {
while (requestsInFlight < maxRequests) {
_RequestInfo request = nextRequest();
if (request == null) {
return;
}
if (logRequests) {
print('Started $request');
}
++requestsInFlight;
Operation requestDone = request.zone.makeOperation(() {
--requestsInFlight;
if (request.onDone != null) {
request.onDone.scheduleAction();
}
if (logRequests) {
print('Ended $request');
}
processPendingRequests();
});
request.start(requestDone);
}
}
}