##// END OF EJS Templates
Added CancelledError, fixed lint warnings
cin -
r172:3969a8fb8049 release v1.4.6 default
parent child
Show More
@@ -0,0 +1,12
1 import { Cancellation } from "./Cancellation";
2 import { ICancellation } from "./interfaces";
3
4 export class CancelledError extends Error {
5 readonly cancellationToken: ICancellation;
6
7 constructor(message = "The operation is cancelled", ct = Cancellation.none) {
8 super(message);
9 this.cancellationToken = ct;
10 this.name = "CancelledError";
11 }
12 }
@@ -1,4 +1,5
1 import { CancellationAggregate } from "./CancellationAggregate";
1 import { CancellationAggregate } from "./CancellationAggregate";
2 import { CancelledError } from "./CancelledError";
2 import { ICancellation, IDestroyable } from "./interfaces";
3 import { ICancellation, IDestroyable } from "./interfaces";
3 import { argumentNotNull, destroyed } from "./safe";
4 import { argumentNotNull, destroyed } from "./safe";
4
5
@@ -57,7 +58,7 export class Cancellation implements ICa
57 if (this._reason)
58 if (this._reason)
58 return;
59 return;
59
60
60 this._reason = (reason = reason || new Error("Operation cancelled"));
61 this._reason = (reason = reason || new CancelledError(undefined, this));
61
62
62 if (this._cbs) {
63 if (this._cbs) {
63 this._cbs.forEach(cb => cb(reason));
64 this._cbs.forEach(cb => cb(reason));
@@ -94,13 +95,13 export class Cancellation implements ICa
94 * no tokens left in the list the method returns `Cancellation.none`.
95 * no tokens left in the list the method returns `Cancellation.none`.
95 *
96 *
96 * @param args The list of cancellation tokens to combine
97 * @param args The list of cancellation tokens to combine
97 * @returns
98 * @returns Aggregated cancellation token
98 */
99 */
99 static combine(...args: ICancellation[]) {
100 static combine(...args: ICancellation[]) {
100 const tokens = args.filter(ct => ct.isSupported());
101 const tokens = args.filter(ct => ct.isSupported());
101 return tokens.length > 1 ?
102 return tokens.length > 1 ?
102 new CancellationAggregate(tokens) :
103 new CancellationAggregate(tokens) :
103 tokens.length == 1 ? tokens[0] :
104 tokens.length === 1 ? tokens[0] :
104 this.none;
105 this.none;
105 }
106 }
106 }
107 }
@@ -26,13 +26,13 export class CancellationAggregate imple
26 destroy();
26 destroy();
27 cb(e);
27 cb(e);
28 }
28 }
29 }
29 };
30
30
31 const destroy = () => subscriptions
31 const destroy = () => subscriptions
32 .splice(0,subscriptions.length) // empty array
32 .splice(0, subscriptions.length) // empty array
33 .forEach(subscription => subscription.destroy()); // cleanup
33 .forEach(subscription => subscription.destroy()); // cleanup
34
34
35 const subscriptions = this._tokens.map(ct => ct.register(once))
35 const subscriptions = this._tokens.map(ct => ct.register(once));
36
36
37 return {
37 return {
38 destroy
38 destroy
@@ -18,7 +18,10 export class AsyncComponent implements I
18
18
19 const guard = async () => {
19 const guard = async () => {
20 try {
20 try {
21 return op(Cancellation.combine(ct, inner));
21 const combined = Cancellation.combine(ct, inner);
22 const result = await op(combined);
23 combined.throwIfRequested();
24 return result;
22 } finally {
25 } finally {
23 // after the operation is complete we need to cleanup the
26 // after the operation is complete we need to cleanup the
24 // resources
27 // resources
@@ -209,7 +209,7 export class LifetimeManager implements
209 _lifetime.store(item);
209 _lifetime.store(item);
210 },
210 },
211 toString() {
211 toString() {
212 return `[object ContainerLifetime, has=${_lifetime.has()}]`
212 return `[object ContainerLifetime, has=${_lifetime.has()}]`;
213 }
213 }
214 };
214 };
215 }
215 }
@@ -29,10 +29,48 export interface IRemovable {
29 remove(): void;
29 remove(): void;
30 }
30 }
31
31
32 /**
33 * Interface for the cancellation token. Cancellation token is
34 * a marker indicating that the cancellation was requested, it
35 * is up to the operation to decide whether to interrupt or
36 * to complete its execution.
37 *
38 * This interface defines several methods of interaction with
39 * the cancellation i.e. either to poll its status or to react
40 * through the callback.
41 */
32 export interface ICancellation {
42 export interface ICancellation {
43 /**
44 * Throws an exception if the cancellation has been requested,
45 * otherwise does nothing.
46 */
33 throwIfRequested(): void;
47 throwIfRequested(): void;
48
49 /**
50 * Checks whether the cancellation is requested.
51 * @returns true is the cancellation has been requested,
52 * otherwise returns false.
53 */
34 isRequested(): boolean;
54 isRequested(): boolean;
55
56 /**
57 * Checks the ability of the token to be signaled.
58 *
59 * @returns true if the token is able to request
60 * the cancellation, false otherwise.
61 */
35 isSupported(): boolean;
62 isSupported(): boolean;
63
64 /**
65 * Registers the callback to be called when the cancellation
66 * is requested.
67 *
68 * @param cb The callback which receives the reason of the
69 * cancellation.
70 * @returns The subscription, after the operation is completed
71 * it should unregister the callback to free resources by
72 * calling the `destroy()` method of the subscription.
73 */
36 register(cb: (e: any) => void): IDestroyable;
74 register(cb: (e: any) => void): IDestroyable;
37 }
75 }
38
76
@@ -34,7 +34,7 test("Nested async configuration", async
34 });
34 });
35
35
36 t.assert(container.resolve("box").getValue(), "The dependency should be set");
36 t.assert(container.resolve("box").getValue(), "The dependency should be set");
37 t.equals(container.resolve("box").getValue(), container.resolve("box").getValue(), "The service should be activated once")
37 t.equals(container.resolve("box").getValue(), container.resolve("box").getValue(), "The service should be activated once");
38 });
38 });
39
39
40 test("Bad fluent config", async t => {
40 test("Bad fluent config", async t => {
General Comments 0
You need to be logged in to leave comments. Login now