##// END OF EJS Templates
added TraceSource tests
cin -
r11:b9900835d201 propose cancellat...
parent child
Show More
@@ -0,0 +1,29
1 define(["tape"], function(tape) {
2 "use strict";
3 var sourceId = '73a633f3-eab8-49b0-8601-07cae710f234';
4 var sourceId2 = '3ba9c7cd-ed77-437b-9a2f-1cbeb1226b5b';
5 tape('Load TraceSource for the module', function(t) {
6 require(["core/log/trace!" + sourceId, "core/log/TraceSource"], function(trace, TraceSource) {
7 t.equal(trace && trace.id, sourceId, "trace should be taken from the loader plugin parameter");
8
9 var count = 0;
10
11 var h = TraceSource.on(function(x) {
12 if(x.id == sourceId || x.id == sourceId2)
13 count++;
14 });
15
16 t.equal(count, 1, "should see created channel immediatelly");
17 t.equal(trace, TraceSource.get(sourceId), "should get same TraceSource from registry");
18 t.equal(count, 1);
19
20 TraceSource.get(sourceId2);
21
22 t.equal(count, 2);
23
24 h.destroy();
25
26 t.end();
27 });
28 });
29 }); No newline at end of file
@@ -0,0 +1,14
1 import * as TraceSource from '@implab/core/log/TraceSource'
2 import * as tape from 'tape';
3
4 const sourceId = 'test/TraceSourceTests';
5
6 tape('', t => {
7 let trace = TraceSource.get(sourceId);
8
9 let h = trace.on((sender,level,msg) => {
10
11 });
12
13 h.destroy();
14 }); No newline at end of file
@@ -1,94 +1,96
1 import { IActivationController } from './IActivationController';
1 import { IActivationController } from './IActivationController';
2 import { IActivatable } from './IActivatable';
2 import { IActivatable } from './IActivatable';
3 import { AsyncComponent } from './AsyncComponent';
3 import { AsyncComponent } from './AsyncComponent';
4 import { ICancellation } from '../ICancellation';
4 import { ICancellation } from '../ICancellation';
5 import { EmptyCancellation } from '../EmptyCancellation';
5 import { EmptyCancellation } from '../EmptyCancellation';
6 import * as log from '@implab/core/log/trace!';
6 import * as TraceSource from '../log/TraceSource';
7
7
8 type Constructor<T = {}> = new (...args: any[]) => T;
8 type Constructor<T = {}> = new (...args: any[]) => T;
9
9
10 const log = TraceSource.get('@implab/core/components/ActivatableMixin');
11
10 function ActivatableMixin<TBase extends Constructor<AsyncComponent>>(Base: TBase) {
12 function ActivatableMixin<TBase extends Constructor<AsyncComponent>>(Base: TBase) {
11 return class extends Base implements IActivatable {
13 return class extends Base implements IActivatable {
12 _controller: IActivationController;
14 _controller: IActivationController;
13
15
14 _active: boolean;
16 _active: boolean;
15
17
16 isActive() {
18 isActive() {
17 return this._active;
19 return this._active;
18 }
20 }
19
21
20 getActivationController() {
22 getActivationController() {
21 return this._controller;
23 return this._controller;
22 }
24 }
23
25
24 setActivationController(controller: IActivationController) {
26 setActivationController(controller: IActivationController) {
25 this._controller = controller;
27 this._controller = controller;
26 }
28 }
27
29
28 async onActivating(ct: ICancellation) {
30 async onActivating(ct: ICancellation) {
29 if (this._controller)
31 if (this._controller)
30 await this._controller.activating(this, ct);
32 await this._controller.activating(this, ct);
31 }
33 }
32
34
33 async onActivated(ct: ICancellation) {
35 async onActivated(ct: ICancellation) {
34 if (this._controller)
36 if (this._controller)
35 await this._controller.activated(this, ct);
37 await this._controller.activated(this, ct);
36 }
38 }
37
39
38 async activate(ct: ICancellation = EmptyCancellation.default) {
40 async activate(ct: ICancellation = EmptyCancellation.default) {
39 if (this.isActive())
41 if (this.isActive())
40 return;
42 return;
41 ct = this.startOperation(ct);
43 ct = this.startOperation(ct);
42 try {
44 try {
43 await this.onActivating(ct);
45 await this.onActivating(ct);
44 this._active = true;
46 this._active = true;
45 try {
47 try {
46 await this.onActivated(ct);
48 await this.onActivated(ct);
47 } catch(e) {
49 } catch(e) {
48 log.error(e);
50 log.error(e);
49 // TODO log error
51 // TODO log error
50 }
52 }
51 this.completeSuccess();
53 this.completeSuccess();
52 } catch (e) {
54 } catch (e) {
53 this.completeFail(e);
55 this.completeFail(e);
54 }
56 }
55 return this.getCompletion();
57 return this.getCompletion();
56 }
58 }
57
59
58 async onDeactivating(ct: ICancellation) {
60 async onDeactivating(ct: ICancellation) {
59 if (this._controller)
61 if (this._controller)
60 await this._controller.deactivating(this, ct);
62 await this._controller.deactivating(this, ct);
61 }
63 }
62
64
63 async onDeactivated(ct: ICancellation) {
65 async onDeactivated(ct: ICancellation) {
64 if (this._controller)
66 if (this._controller)
65 await this._controller.deactivated(this, ct);
67 await this._controller.deactivated(this, ct);
66 }
68 }
67
69
68 async deactivate(ct: ICancellation = EmptyCancellation.default) {
70 async deactivate(ct: ICancellation = EmptyCancellation.default) {
69 if (!this.isActive())
71 if (!this.isActive())
70 return;
72 return;
71 ct = this.startOperation(ct);
73 ct = this.startOperation(ct);
72 try {
74 try {
73 await this.onDeactivating(ct);
75 await this.onDeactivating(ct);
74 this._active = false;
76 this._active = false;
75 try {
77 try {
76 await this.onDeactivated(ct);
78 await this.onDeactivated(ct);
77 } catch {
79 } catch {
78 // TODO log error
80 // TODO log error
79 }
81 }
80 this.completeSuccess();
82 this.completeSuccess();
81 } catch (e) {
83 } catch (e) {
82 this.completeFail(e);
84 this.completeFail(e);
83 }
85 }
84 return this.getCompletion();
86 return this.getCompletion();
85 }
87 }
86
88
87 }
89 }
88 }
90 }
89
91
90 namespace ActivatableMixin {
92 namespace ActivatableMixin {
91
93
92 }
94 }
93
95
94 export = ActivatableMixin; No newline at end of file
96 export = ActivatableMixin;
@@ -1,175 +1,175
1 import * as format from '../text/format'
1 import * as format from '../text/format'
2 import { argumentNotNull } from '../safe';
2 import { argumentNotNull } from '../safe';
3
3
4 interface TraceEventHandler {
4 interface TraceEventHandler {
5 (sender: TraceSource, level: number, arg: any): void;
5 (sender: TraceSource, level: number, arg: any): void;
6 }
6 }
7
7
8 interface TraceSourceHandler {
8 interface TraceSourceHandler {
9 (source: TraceSource): void;
9 (source: TraceSource): void;
10 }
10 }
11
11
12 interface Destroyable {
12 interface Destroyable {
13 destroy();
13 destroy();
14 }
14 }
15
15
16 class Registry {
16 class Registry {
17 static readonly instance = new Registry();
17 static readonly instance = new Registry();
18
18
19 private _registry: object = new Object();
19 private _registry: object = new Object();
20 private _listeners: object = new Object();
20 private _listeners: object = new Object();
21 private _nextCookie: number = 1;
21 private _nextCookie: number = 1;
22
22
23 get(id: any): TraceSource {
23 get(id: any): TraceSource {
24 argumentNotNull(id, "id");
24 argumentNotNull(id, "id");
25
25
26 if (this._registry[id])
26 if (this._registry[id])
27 return this._registry[id];
27 return this._registry[id];
28
28
29 var source = new TraceSource(id);
29 var source = new TraceSource(id);
30 this._registry[id] = source;
30 this._registry[id] = source;
31 this._onNewSource(source);
31 this._onNewSource(source);
32
32
33 return source;
33 return source;
34 }
34 }
35
35
36 add(id: any, source: TraceSource) {
36 add(id: any, source: TraceSource) {
37 argumentNotNull(id, "id");
37 argumentNotNull(id, "id");
38 argumentNotNull(source, "source");
38 argumentNotNull(source, "source");
39
39
40 this._registry[id] = source;
40 this._registry[id] = source;
41 this._onNewSource(source);
41 this._onNewSource(source);
42 }
42 }
43
43
44 _onNewSource(source: TraceSource) {
44 _onNewSource(source: TraceSource) {
45 for (let i in this._listeners)
45 for (let i in this._listeners)
46 this._listeners[i].call(null, source);
46 this._listeners[i].call(null, source);
47 }
47 }
48
48
49 on(handler: TraceSourceHandler): Destroyable {
49 on(handler: TraceSourceHandler): Destroyable {
50 argumentNotNull(handler, "handler");
50 argumentNotNull(handler, "handler");
51 var me = this;
51 var me = this;
52
52
53 var cookie = this._nextCookie++;
53 var cookie = this._nextCookie++;
54
54
55 this._listeners[cookie] = handler;
55 this._listeners[cookie] = handler;
56
56
57 for (let i in this._registry)
57 for (let i in this._registry)
58 handler(this._registry[i]);
58 handler(this._registry[i]);
59
59
60 return {
60 return {
61 destroy() {
61 destroy() {
62 delete me._listeners[cookie];
62 delete me._listeners[cookie];
63 }
63 }
64 };
64 };
65 }
65 }
66 }
66 }
67
67
68 class TraceSource {
68 class TraceSource {
69
69
70 readonly id: any
70 readonly id: any
71
71
72 // using array will provide faster iteration the with object
72 // using array will provide faster iteration the with object
73 private _handlers: Array<TraceEventHandler> = new Array<TraceEventHandler>();
73 private _handlers: Array<TraceEventHandler> = new Array<TraceEventHandler>();
74
74
75 level: number
75 level: number
76
76
77 constructor(id: any) {
77 constructor(id: any) {
78 this.id = id || new Object();
78 this.id = id || new Object();
79 }
79 }
80
80
81 on(handler: TraceEventHandler): Destroyable {
81 on(handler: TraceEventHandler): Destroyable {
82 argumentNotNull(handler, "handler");
82 argumentNotNull(handler, "handler");
83 var me = this;
83 var me = this;
84 me._handlers.push(handler);
84 me._handlers.push(handler);
85
85
86 return {
86 return {
87 destroy() {
87 destroy() {
88 me.remove(handler);
88 me.remove(handler);
89 }
89 }
90 }
90 }
91 }
91 }
92
92
93 remove(handler: TraceEventHandler): void {
93 remove(handler: TraceEventHandler): void {
94 let i = this._handlers.indexOf(handler);
94 let i = this._handlers.indexOf(handler);
95 if (i >= 0)
95 if (i >= 0)
96 this._handlers.splice(i, 1);
96 this._handlers.splice(i, 1);
97 }
97 }
98
98
99 protected emit(level: number, arg: any) {
99 protected emit(level: number, arg: any) {
100 this._handlers.forEach(h => {
100 this._handlers.forEach(h => {
101 try {
101 try {
102 h(this, level, arg);
102 h(this, level, arg);
103 } catch (e) {
103 } catch (e) {
104 // suppress error in log handlers
104 // suppress error in log handlers
105 }
105 }
106 });
106 });
107 }
107 }
108
108
109 isDebugEnabled() {
109 isDebugEnabled() {
110 return this.level >= TraceSource.DebugLevel;
110 return this.level >= TraceSource.DebugLevel;
111 }
111 }
112
112
113 debug(msg: string, ...args: any[]) {
113 debug(msg: string, ...args: any[]) {
114 if (this.isEnabled(TraceSource.DebugLevel))
114 if (this.isEnabled(TraceSource.DebugLevel))
115 this.emit(TraceSource.DebugLevel, format(msg, args));
115 this.emit(TraceSource.DebugLevel, format(msg, args));
116 }
116 }
117
117
118 isLogEnabled() {
118 isLogEnabled() {
119 return this.level >= TraceSource.LogLevel;
119 return this.level >= TraceSource.LogLevel;
120 }
120 }
121
121
122 log(msg: string, ...args: any[]) {
122 log(msg: string, ...args: any[]) {
123 if (this.isEnabled(TraceSource.LogLevel))
123 if (this.isEnabled(TraceSource.LogLevel))
124 this.emit(TraceSource.LogLevel, format(msg, args));
124 this.emit(TraceSource.LogLevel, format(msg, args));
125 }
125 }
126
126
127 isWarnEnabled() {
127 isWarnEnabled() {
128 return this.level >= TraceSource.WarnLevel;
128 return this.level >= TraceSource.WarnLevel;
129 }
129 }
130
130
131 warn(msg: string, ...args: any[]) {
131 warn(msg: string, ...args: any[]) {
132 if (this.isEnabled(TraceSource.WarnLevel))
132 if (this.isEnabled(TraceSource.WarnLevel))
133 this.emit(TraceSource.WarnLevel, format(msg, args));
133 this.emit(TraceSource.WarnLevel, format(msg, args));
134 }
134 }
135
135
136 isErrorEnabled() {
136 isErrorEnabled() {
137 return this.level >= TraceSource.ErrorLevel;
137 return this.level >= TraceSource.ErrorLevel;
138 }
138 }
139
139
140 error(msg: string, ...args: any[]) {
140 error(msg: string, ...args: any[]) {
141 if (this.isEnabled(TraceSource.ErrorLevel))
141 if (this.isEnabled(TraceSource.ErrorLevel))
142 this.emit(TraceSource.ErrorLevel, format(msg, args));
142 this.emit(TraceSource.ErrorLevel, format(msg, args));
143 }
143 }
144
144
145 isEnabled(level: number) {
145 isEnabled(level: number) {
146 return (this.level >= level);
146 return (this.level >= level);
147 }
147 }
148
148
149 traceEvent(level: number, arg: any) {
149 traceEvent(level: number, arg: any) {
150 if (this.isEnabled(level))
150 if (this.isEnabled(level))
151 this.emit(level, arg);
151 this.emit(level, arg);
152 }
152 }
153
153
154 static on(handler: TraceSourceHandler) {
154 static on(handler: TraceSourceHandler) {
155 Registry.instance.on(handler);
155 return Registry.instance.on(handler);
156 }
156 }
157
157
158 static get(id: any) {
158 static get(id: any) {
159 return Registry.instance.get(id);
159 return Registry.instance.get(id);
160 }
160 }
161 }
161 }
162
162
163 namespace TraceSource {
163 namespace TraceSource {
164 export const DebugLevel = 400;
164 export const DebugLevel = 400;
165
165
166 export const LogLevel = 300;
166 export const LogLevel = 300;
167
167
168 export const WarnLevel = 200;
168 export const WarnLevel = 200;
169
169
170 export const ErrorLevel = 100;
170 export const ErrorLevel = 100;
171
171
172 export const SilentLevel = 0;
172 export const SilentLevel = 0;
173 }
173 }
174
174
175 export = TraceSource; No newline at end of file
175 export = TraceSource;
@@ -1,1 +1,1
1 define(["./dummy", "./example", "./ActivatableTests"]); No newline at end of file
1 define(["./ActivatableTests", "./trace-test"]); No newline at end of file
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now