##// END OF EJS Templates
rewritten TraceSource
cin -
r10:57344e243cdf propose cancellat...
parent child
Show More
@@ -0,0 +1,12
1 declare interface ILog {
2 debug(...args: any[]): void;
3 log(...args: any[]): void;
4 warn(...args: any[]): void;
5 error(...args: any[]): void;
6 }
7
8 declare module "@implab/core/log/trace!*" {
9 const channel: ILog;
10
11 export = channel;
12 } No newline at end of file
@@ -0,0 +1,1
1 export declare function argumentNotNull(v: any, paramName: string); No newline at end of file
@@ -133,7 +133,7
133 },
133 },
134 "minimist": {
134 "minimist": {
135 "version": "0.0.5",
135 "version": "0.0.5",
136 "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.5.tgz",
136 "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.5.tgz",
137 "integrity": "sha1-16oye87PUY+RBqxrjwA/o7zqhWY=",
137 "integrity": "sha1-16oye87PUY+RBqxrjwA/o7zqhWY=",
138 "dev": true
138 "dev": true
139 },
139 },
@@ -319,9 +319,9
319 }
319 }
320 },
320 },
321 "requirejs": {
321 "requirejs": {
322 "version": "2.3.5",
322 "version": "2.3.6",
323 "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.5.tgz",
323 "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz",
324 "integrity": "sha512-svnO+aNcR/an9Dpi44C7KSAy5fFGLtmPbaaCeQaklUz8BQhS64tWWIIlvEA5jrWICzlO/X9KSzSeXFnZdBu8nw==",
324 "integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==",
325 "dev": true
325 "dev": true
326 },
326 },
327 "resolve": {
327 "resolve": {
@@ -413,9 +413,9
413 }
413 }
414 },
414 },
415 "typescript": {
415 "typescript": {
416 "version": "2.9.2",
416 "version": "3.0.3",
417 "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz",
417 "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.0.3.tgz",
418 "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==",
418 "integrity": "sha512-kk80vLW9iGtjMnIv11qyxLqZm20UklzuR2tL0QAnDIygIUIemcZMxlMWudl9OOt76H3ntVzcTiddQ1/pAAJMYg==",
419 "dev": true
419 "dev": true
420 },
420 },
421 "wrappy": {
421 "wrappy": {
@@ -14,6 +14,10 requirejs.config({
14 {
14 {
15 name: "test",
15 name: "test",
16 location: "build/test"
16 location: "build/test"
17 },
18 {
19 name: "dojo",
20 location: "node_modules/dojo"
17 }
21 }
18 ],
22 ],
19 nodeRequire: require
23 nodeRequire: require
@@ -1,116 +1,50
1 define(["../text/format"], function (format) {
1 define(["./TraceSource"], function (TraceSource) {
2 'use strict';
2 'use strict';
3
3
4 var listeners = [];
4 return {
5 var channels = {};
6
7 var Trace = function (name) {
8 this.name = name;
9 this._subscribers = [];
10 };
11
12 Trace.prototype.debug = function () {
13 if (Trace.level >= 4)
14 this.notify("debug", format.apply(null, arguments));
15 };
16
17 Trace.prototype.log = function () {
18 if (Trace.level >= 3)
19 this.notify("log", format.apply(null, arguments));
20 };
21
22 Trace.prototype.warn = function () {
23 if (Trace.level >= 2)
24 this.notify("warn", format.apply(null, arguments));
25
26 };
27
5
28 Trace.prototype.error = function () {
6 on: function (filter, cb) {
29 if (Trace.level >= 1)
7 if (arguments.length == 1) {
30 this.notify("error", format.apply(null, arguments));
8 cb = filter;
31 };
9 filter = undefined;
32
10 }
33 Trace.prototype.notify = function (name, msg) {
11 var test;
34 var me = this;
12 if (filter instanceof RegExp) {
35 me._subscribers.forEach(function (cb) {
13 test = function (chId) {
36 cb(me, name, msg);
14 return filter.test(chId);
37 });
15 };
38 };
16 } else if (filter instanceof Function) {
39
17 test = filter;
40 Trace.prototype.subscribe = function (cb) {
18 } else if (filter) {
41 this._subscribers.push(cb);
19 test = function (chId) {
42 };
20 return chId == filter;
43
21 };
44 Trace.prototype.toString = function () {
22 }
45 return this.name;
46 };
47
48 Trace.createChannel = function (type, name, cb) {
49 var chId = name;
50 if (channels[chId])
51 return channels[chId];
52
53 var channel = new type(chId);
54 channels[chId] = channel;
55
56 Trace._onNewChannel(chId, channel);
57 cb(channel);
58 };
59
23
60 Trace._onNewChannel = function (chId, ch) {
24 if (test) {
61 listeners.forEach(function (listener) {
25 TraceSource.on(function (source) {
62 listener(chId, ch);
26 if (test(source.id))
63 });
27 source.on(cb);
64 };
28 });
65
29 } else {
66 Trace.on = function (filter, cb) {
30 TraceSource.on(function (source) {
67 if (arguments.length == 1) {
31 source.on(cb);
68 cb = filter;
32 });
69 filter = undefined;
33 }
70 }
34 },
71 var d, test;
72 if (filter instanceof RegExp) {
73 test = function (chId) {
74 return filter.test(chId);
75 };
76 } else if (filter instanceof Function) {
77 test = filter;
78 } else if (filter) {
79 test = function (chId) {
80 return chId == filter;
81 };
82 }
83
35
84 if (test) {
36 load: function (id, require, cb) {
85 d = function(chId, ch) {
37 if (id) {
86 if(test(chId))
38 cb(TraceSource.get(id));
87 ch.subscribe(cb);
39 } else if (require.module && require.module.mid) {
88 };
40 cb(TraceSource.get(require.module.mid));
89 } else {
41 } else {
90 d = function(chId, ch) {
42 require(['module'], function (module) {
91 ch.subscribe(cb);
43 cb(TraceSource.get(module && module.id));
92 };
44 });
93 }
45 }
94 listeners.push(d);
46 },
95
96 for(var chId in channels)
97 d(chId,channels[chId]);
98 };
99
47
100 Trace.load = function (id, require, cb) {
48 dynamic: true,
101 if (id)
102 Trace.createChannel(Trace, id, cb);
103 else if (require.module && require.module.mid)
104 Trace.createChannel(Trace, require.module.mid, cb);
105 else
106 require(['module'], function (module) {
107 Trace.createChannel(Trace, module && module.id, cb);
108 });
109 };
49 };
110
111 Trace.dynamic = true;
112
113 Trace.level = 4;
114
115 return Trace;
116 }); No newline at end of file
50 });
@@ -3,6 +3,7 import { IActivatable } from './IActivat
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
7
7 type Constructor<T = {}> = new (...args: any[]) => T;
8 type Constructor<T = {}> = new (...args: any[]) => T;
8
9
@@ -43,7 +44,8 function ActivatableMixin<TBase extends
43 this._active = true;
44 this._active = true;
44 try {
45 try {
45 await this.onActivated(ct);
46 await this.onActivated(ct);
46 } catch {
47 } catch(e) {
48 log.error(e);
47 // TODO log error
49 // TODO log error
48 }
50 }
49 this.completeSuccess();
51 this.completeSuccess();
@@ -1,103 +1,162
1 import * as TraceEventArgs from './TraceEventArgs'
2 import * as format from '../text/format'
1 import * as format from '../text/format'
2 import { argumentNotNull } from '../safe';
3
3
4 interface Handler {
4 interface TraceEventHandler {
5 (arg: TraceEventArgs): void;
5 (sender: TraceSource, level: number, arg: any): void;
6 }
7
8 interface TraceSourceHandler {
9 (source: TraceSource): void;
6 }
10 }
7
11
8 interface Destroyable {
12 interface Destroyable {
9 destroy();
13 destroy();
10 }
14 }
11
15
12 class HandlerDescriptor implements Destroyable {
16 class Registry {
13 private _target: TraceSource
17 static readonly instance = new Registry();
18
19 private _registry: object = new Object();
20 private _listeners: object = new Object();
21 private _nextCookie: number = 1;
14
22
15 readonly handler: Handler;
23 get(id: any): TraceSource {
24 argumentNotNull(id, "id");
25
26 if (this._registry[id])
27 return this._registry[id];
16
28
17 constructor(target: TraceSource, handler: Handler) {
29 var source = new TraceSource(id);
18 this._target = target;
30 this._registry[id] = source;
19 this.handler = handler;
31 this._onNewSource(source);
32
33 return source;
20 }
34 }
21
35
22 destroy() {
36 add(id: any, source: TraceSource) {
23 this._target.remove(this);
37 argumentNotNull(id, "id");
38 argumentNotNull(source, "source");
39
40 this._registry[id] = source;
41 this._onNewSource(source);
42 }
43
44 _onNewSource(source: TraceSource) {
45 for (let i in this._listeners)
46 this._listeners[i].call(null, source);
47 }
48
49 on(handler: TraceSourceHandler): Destroyable {
50 argumentNotNull(handler, "handler");
51 var me = this;
52
53 var cookie = this._nextCookie++;
54
55 this._listeners[cookie] = handler;
56
57 for (let i in this._registry)
58 handler(this._registry[i]);
59
60 return {
61 destroy() {
62 delete me._listeners[cookie];
63 }
64 };
24 }
65 }
25 }
66 }
26
67
68 class TraceSource {
27
69
28 class TraceSource {
29 readonly id: any
70 readonly id: any
30
71
31 private _handlers: Array<HandlerDescriptor>
72 // using array will provide faster iteration the with object
73 private _handlers: Array<TraceEventHandler> = new Array<TraceEventHandler>();
32
74
33 level: number
75 level: number
34
76
35 constructor(id: any) {
77 constructor(id: any) {
36 this.id = id || new Object();
78 this.id = id || new Object();
37 this._handlers = new Array<HandlerDescriptor>();
38 }
79 }
39
80
40 on(handler: Handler): Destroyable {
81 on(handler: TraceEventHandler): Destroyable {
41 if (!handler)
82 argumentNotNull(handler, "handler");
42 throw new Error("A handler must be specified");
83 var me = this;
84 me._handlers.push(handler);
43
85
44 let d = new HandlerDescriptor(this, handler)
86 return {
45
87 destroy() {
46 this._handlers.push(d);
88 me.remove(handler);
47
89 }
48 return d;
90 }
49 }
91 }
50
92
51 remove(cookie: any): void {
93 remove(handler: TraceEventHandler): void {
52 let i = this._handlers.indexOf(cookie);
94 let i = this._handlers.indexOf(handler);
53 if (i >= 0)
95 if (i >= 0)
54 this._handlers.splice(i, 1);
96 this._handlers.splice(i, 1);
55 }
97 }
56
98
57 protected emit(level: number, msg: string, ...args: any[]) {
99 protected emit(level: number, arg: any) {
58 if (level <= this.level) {
100 this._handlers.forEach(h => {
59 let event = new TraceEventArgs(this, format(msg, args));
101 try {
60
102 h(this, level, arg);
61 this._handlers.forEach(d => {
103 } catch (e) {
62 try {
104 // suppress error in log handlers
63 d.handler.call(null, event);
105 }
64 } catch {
106 });
65 // suppress error in log handlers
66 }
67 });
68 }
69 }
107 }
70
108
71 isDebugEnabled() {
109 isDebugEnabled() {
72 return this.level >= TraceSource.DebugLevel;
110 return this.level >= TraceSource.DebugLevel;
73 }
111 }
74
112
75 debug(msg: string, ...args: any[]): void {
113 debug(msg: string, ...args: any[]) {
76 this.emit(TraceSource.DebugLevel, msg, args);
114 if (this.isEnabled(TraceSource.DebugLevel))
115 this.emit(TraceSource.DebugLevel, format(msg, args));
77 }
116 }
78
117
79 isLogEnabled() {
118 isLogEnabled() {
80 return this.level >= TraceSource.LogLevel;
119 return this.level >= TraceSource.LogLevel;
81 }
120 }
82
121
83 log(msg: string, ...args: any[]): void {
122 log(msg: string, ...args: any[]) {
84 this.emit(TraceSource.LogLevel, msg, args);
123 if (this.isEnabled(TraceSource.LogLevel))
124 this.emit(TraceSource.LogLevel, format(msg, args));
85 }
125 }
86
126
87 isWarnEnabled() {
127 isWarnEnabled() {
88 return this.level >= TraceSource.WarnLevel;
128 return this.level >= TraceSource.WarnLevel;
89 }
129 }
90
130
91 warn(msg: string, ...args: any[]): void {
131 warn(msg: string, ...args: any[]) {
92 this.emit(TraceSource.WarnLevel, msg, args);
132 if (this.isEnabled(TraceSource.WarnLevel))
133 this.emit(TraceSource.WarnLevel, format(msg, args));
93 }
134 }
94
135
95 isErrorEnabled() {
136 isErrorEnabled() {
96 return this.level >= TraceSource.ErrorLevel;
137 return this.level >= TraceSource.ErrorLevel;
97 }
138 }
98
139
99 error(msg: string, ...args: any[]): void {
140 error(msg: string, ...args: any[]) {
100 this.emit(TraceSource.ErrorLevel, msg, args);
141 if (this.isEnabled(TraceSource.ErrorLevel))
142 this.emit(TraceSource.ErrorLevel, format(msg, args));
143 }
144
145 isEnabled(level: number) {
146 return (this.level >= level);
147 }
148
149 traceEvent(level: number, arg: any) {
150 if (this.isEnabled(level))
151 this.emit(level, arg);
152 }
153
154 static on(handler: TraceSourceHandler) {
155 Registry.instance.on(handler);
156 }
157
158 static get(id: any) {
159 return Registry.instance.get(id);
101 }
160 }
102 }
161 }
103
162
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