LCOV - code coverage report

Current view
top level - /src - worker_task.dart
Test
lcov.info
Date
2022-04-02
Legend
Lines
hit
not hit
Branches
taken
not taken
# not executed
HitTotalCoverage
Lines798790.8%
Functions00-
Branches00-
Each row represents a line of source code
LineBranchHitsSource code
1import 'dart:async';
2
3import 'perf_counter.dart';
4import 'cancellation_token.dart';
5import 'squadron_error.dart';
6import 'squadron_exception.dart';
7import 'worker.dart';
8import 'worker_exception.dart';
9import 'worker_pool.dart';
10import 'worker_service.dart';
11
12/// Base worker task class
13abstract class Task<T> {
14 /// Flag indicating whether the task is actually being executed.
15 bool get isRunning;
16
17 /// Flag indicating whether the task has completed.
18 bool get isFinished;
19
20 /// Flag indicating whether the task has been cancelled.
21 bool get isCancelled;
22
23 /// Duration between the moment the task was posted, and the moment it was assigned to a [Worker].
24 Duration get waitTime;
25
26 /// Duration between the moment the task was assigned to a [Worker], and the moment it finished executing.
27 Duration get runningTime;
28
29 /// Cancels the task. If the task is still pending, cancellation is effective immediately with a
30 /// [CancelledException]. For a running [ValueTask], cancellation is ignored and the task's [ValueTask.value]
31 /// will eventually complete. For a running [StreamTask], cancellation will be effective after receiving the
32 /// next value and the task's [StreamTask.stream] will be closed. It should be noted that cancellation of
33 /// running tasks will not be notified to platform workers. To give running tasks a chance to get notified
34 /// of cancellation, a [CancellationToken] should be passed to the tasks at the time they are created.
35 void cancel([String? message]);
36}
37
38/// Class representing a [Task] returning a single value.
39abstract class ValueTask<T> extends Task<T> {
40 /// The task's value provided as a [Future].
41 Future<T> get value;
42}
43
44/// Class representing a [Task] returning a stream of values.
45abstract class StreamTask<T> extends Task<T> {
46 /// The task's stream.
47 Stream<T> get stream;
48}
49
50/// [WorkerTask] registered in the [WorkerPool].
51class WorkerTask<T, W extends Worker> implements ValueTask<T>, StreamTask<T> {
52 /// Creates a new [ValueTask].
532 WorkerTask.value(this._computer, this._counter)
541 : assert(_computer != null),
551 _completer = Completer<T>(),
56 _producer = null,
57 _streamer = null {
582 _submitted = _timeStamp();
59 }
60
61 /// Creates a new [StreamTask].
622 WorkerTask.stream(this._producer, this._counter)
631 : assert(_producer != null),
642 _streamer = StreamController<T>(),
65 _computer = null,
66 _completer = null {
672 _submitted = _timeStamp();
68 }
69
703 static int _timeStamp() => DateTime.now().microsecondsSinceEpoch;
71
721 late final int _submitted;
73
741 @override
751 bool get isRunning =>
763 _executed != null && _finished == null && _cancelled == null;
77 int? _executed;
78
791 @override
801 bool get isFinished =>
814 _executed != null && _finished != null && _cancelled == null;
82 int? _finished;
83
841 @override
852 bool get isCancelled => _cancelled != null;
86 int? _cancelled;
87
880 @override
890 Duration get waitTime => Duration(
900 microseconds: (_executed ?? _cancelled ?? _timeStamp()) - _submitted);
91
920 @override
930 Duration get runningTime => _executed == null
94 ? Duration.zero
950 : Duration(
96 microseconds:
970 (_cancelled ?? _finished ?? _timeStamp()) - _executed!);
98
992 void _completeWithError(Exception exception) {
1003 if (!_completer!.isCompleted) {
1013 _completer!.completeError(exception);
102 }
1031 }
104
1051 void _completeWithResult(dynamic data) {
1063 if (!_completer!.isCompleted) {
1073 _completer!.complete(data);
108 }
109 }
110
1112 void _close([Exception? exception]) {
1123 if (!_streamer!.isClosed) {
1131 if (exception != null) {
1143 _streamer!.addError(exception);
115 }
1163 _streamer!.close();
117 }
1181 }
119
1201 @override
1211 void cancel([String? message]) {
1222 if (_cancelled == null) {
1233 _cancelled = _timeStamp();
1243 if (_completer != null && _executed == null) {
1255 _wrapUp(() => _completeWithError(CancelledException(message: message)),
126 false);
1272 } else if (_streamer != null) {
1285 _wrapUp(() => _close(CancelledException(message: message)), false);
129 }
130 }
1311 }
132
1332 void _wrapUp(SquadronCallback wrapper, bool success) async {
1342 if (_finished == null) {
1352 _finished = _timeStamp();
1365 _counter?.update(_finished! - _executed!, success);
1372 wrapper();
138 }
1391 }
140
1412 Future _runFuture(W worker, Future<T> Function(W worker) computer,
142 Completer completer) async {
1432 if (completer.isCompleted) return;
144
1451 try {
1461 if (isCancelled) throw CancelledException();
1473 final value = await computer(worker);
1484 _wrapUp(() => _completeWithResult(value), true);
1491 } catch (ex, st) {
1502 final wex = SquadronException.from(error: ex, stackTrace: st);
1514 _wrapUp(() => _completeWithError(wex), false);
152 }
1531 }
154
1552 Future _runStream(W worker, Stream<T> Function(W worker) producer,
156 StreamController streamer) async {
1572 if (streamer.isClosed) return;
158
1591 try {
1601 if (isCancelled) throw CancelledException();
1614 await for (var value in producer(worker)) {
1621 streamer.add(value);
1631 if (isCancelled) throw CancelledException();
164 }
1654 _wrapUp(() => _close(), true);
1661 } catch (ex, st) {
1672 final wex = SquadronException.from(error: ex, stackTrace: st);
1684 _wrapUp(() => _close(wex), false);
169 }
1701 }
171
1722 Future run(W worker) {
1733 _executed = _timeStamp();
1743 if (_computer != null && _completer != null) {
1754 return _runFuture(worker, _computer!, _completer!);
1763 } else if (_producer != null && _streamer != null) {
1774 return _runStream(worker, _producer!, _streamer!);
178 } else {
1790 throw newSquadronError('invalid worker task state');
180 }
1811 }
182
183 final PerfCounter? _counter;
184
185 final Future<T> Function(W worker)? _computer;
186 final Completer<T>? _completer;
187
1881 @override
1893 Future<T> get value => _completer!.future;
190
191 final Stream<T> Function(W worker)? _producer;
192 final StreamController<T>? _streamer;
193
1941 @override
1953 Stream<T> get stream => _streamer!.stream;
196}
Choose Features