Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(551)

Side by Side Diff: lib/src/errors.dart

Issue 928663003: Add IsolateRunner as a helper around Isolate. (Closed) Base URL: https://github.com/dart-lang/isolate.git@master
Patch Set: Add .status. Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/runner.dart ('k') | lib/src/functionref.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 // TODO(lrn): This should be in package:async?
6 /**
7 * Helper functions for working with errors.
8 *
9 * The [MultiError] class combines multiple errors into one object,
10 * and the [MultiError.wait] function works like [Future.wait] except
11 * that it returns all the errors.
12 */
13 library pkg.isolate.errors;
14
15 import "dart:async";
16
17 class MultiError extends Error {
18 // Limits the number of lines included from each error's error message.
19 // A best-effort attempt is made at keeping below this number of lines
20 // in the output.
21 // If there are too many errors, they will all get at least one line.
22 static const int _MAX_LINES = 55;
23 // Minimum number of lines in the toString for each error.
24 static const int _MIN_LINES_PER_ERROR = 1;
25
26 /** The actual errors. */
27 final List errors;
28
29 /**
30 * Create a `MultiError` based on a list of errors.
31 *
32 * The errors represent errors of a number of individual operations.
33 *
34 * The list may contain `null` values, if the index of the error in the
35 * list is useful.
36 */
37 MultiError(this.errors);
38
39 /**
40 * Waits for all [futures] to complete, like [Future.wait].
41 *
42 * Where `Future.wait` only reports one error, even if multiple
43 * futures complete with errors, this function will complete
44 * with a [MultiError] if more than one future completes with an error.
45 *
46 * The order of values is not preserved (if that is needed, use
47 * [wait]).
48 */
49 static Future<List> waitUnordered(Iterable<Future> futures,
50 {cleanUp(successResult)}) {
51 Completer completer;
52 int count = 0;
53 int errors = 0;
54 int values = 0;
55 // Initilized to `new List(count)` when count is known.
56 // Filled up with values on the left, errors on the right.
57 // Order is not preserved.
58 List results;
59 void checkDone() {
60 if (errors + values < count) return;
61 if (errors == 0) {
62 completer.complete(results);
63 return;
64 }
65 var errorList = results.sublist(results.length - errors);
66 completer.completeError(new MultiError(errorList));
67 };
68 var handleValue = (v) {
69 // If this fails because [results] is null, there is a future
70 // which breaks the Future API by completing immediately when
71 // calling Future.then, probably by misusing a synchronous completer.
72 results[values++] = v;
73 if (errors > 0 && cleanUp != null) {
74 new Future.sync(() => cleanUp(v));
75 }
76 checkDone();
77 };
78 var handleError = (e, s) {
79 if (errors == 0 && cleanUp != null) {
80 for (int i = 0; i < values; i++) {
81 var value = results[i];
82 if (value != null) new Future.sync(() => cleanUp(value));
83 }
84 }
85 results[results.length - ++errors] = e;
86 checkDone();
87 };
88 for (Future future in futures) {
89 count++;
90 future.then(handleValue, onError: handleError);
91 }
92 if (count == 0) return new Future.value(new List(0));
93 results = new List(count);
94 completer = new Completer();
95 return completer.future;
96 }
97
98 /**
99 * Waits for all [futures] to complete, like [Future.wait].
100 *
101 * Where `Future.wait` only reports one error, even if multiple
102 * futures complete with errors, this function will complete
103 * with a [MultiError] if more than one future completes with an error.
104 *
105 * The order of values is preserved, and if any error occurs, the
106 * [MultiError.errors] list will have errors in the corresponding slots,
107 * and `null` for non-errors.
108 */
109 Future<List> wait(Iterable<Future> futures,
110 {cleanUp(successResult)}) {
111 Completer completer;
112 int count = 0;
113 bool hasError = false;
114 int completed = 0;
115 // Initalized to `new List(count)` when count is known.
116 // Filled with values until the first error, then cleared
117 // and filled with errors.
118 List results;
119 void checkDone() {
120 completed++;
121 if (completed < count) return;
122 if (!hasError) {
123 completer.complete(results);
124 return;
125 }
126 completer.completeError(new MultiError(results));
127 };
128 for (Future future in futures) {
129 int i = count;
130 count++;
131 future.then((v) {
132 if (!hasError) {
133 results[i] = v;
134 } else if (cleanUp != null) {
135 new Future.sync(() => cleanUp(v));
136 }
137 checkDone();
138 }, onError: (e, s) {
139 if (!hasError) {
140 if (cleanUp != null) {
141 for (int i = 0; i < results.length; i++) {
142 var result = results[i];
143 if (result != null) new Future.sync(() => cleanUp(result));
144 }
145 }
146 results.fillRange(0, results.length, null);
147 hasError = true;
148 }
149 results[i] = e;
150 checkDone();
151 });
152 }
153 if (count == 0) return new Future.value(new List(0));
154 results = new List(count);
155 completer = new Completer();
156 return completer.future;
157 }
158
159
160 String toString() {
161 StringBuffer buffer = new StringBuffer();
162 buffer.write("Multiple Errors:\n");
163 int linesPerError = _MAX_LINES ~/ errors.length;
164 if (linesPerError < _MIN_LINES_PER_ERROR) {
165 linesPerError = _MIN_LINES_PER_ERROR;
166 }
167
168 for (int index = 0; index < errors.length; index++) {
169 var error = errors[index];
170 if (error == null) continue;
171 String errorString = error.toString();
172 int end = 0;
173 for (int i = 0; i < linesPerError; i++) {
174 end = errorString.indexOf('\n', end) + 1;
175 if (end == 0) {
176 end = errorString.length;
177 break;
178 }
179 }
180 buffer.write("#$index: ");
181 buffer.write(errorString.substring(0, end));
182 if (end < errorString.length) {
183 buffer.write("...\n");
184 }
185 }
186 return buffer.toString();
187 }
188 }
OLDNEW
« no previous file with comments | « lib/runner.dart ('k') | lib/src/functionref.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698