1- import fs from 'fs' ;
21import Span from './Span.js' ;
32
4- export default class Tracer {
5- private activeSpans : Map < string , Span > = new Map ( ) ;
6- private spanFile = 'spans.json' ;
7- private jsonlStream = fs . createWriteStream ( 'spans.jsonl' , { flags : 'a' } ) ;
3+ class Tracer {
4+ protected activeSpans : Map < string , Span > = new Map ( ) ;
5+ protected queue : Array < Span > = [ ] ;
6+ protected resolveWaitChunksP : ( ( ) => void ) | undefined ;
7+ protected ended : boolean = false ;
8+
9+ protected queueSpan ( span : Span ) {
10+ this . queue . push ( span ) ;
11+ if ( this . resolveWaitChunksP != null ) this . resolveWaitChunksP ( ) ;
12+ }
813
914 public startSpan ( name : string , parentSpanId ?: string ) : string {
1015 const span = new Span ( name , parentSpanId ) ;
@@ -14,45 +19,31 @@ export default class Tracer {
1419 this . activeSpans . get ( parentSpanId ) ! . children . push ( span ) ;
1520 }
1621
17- this . saveSpansToFile ( ) ;
1822 return span . spanId ;
1923 }
2024
21- public endSpan ( spanId : string ) : Span | null {
25+ public endSpan ( spanId : string ) : Span | undefined {
2226 const span = this . activeSpans . get ( spanId ) ;
23- if ( ! span ) return null ;
27+ if ( ! span ) return ;
2428
2529 span . close ( ) ;
26- this . jsonlStream . write ( JSON . stringify ( span . toJSON ( ) ) + '\n' ) ;
27- this . saveSpansToFile ( ) ;
30+ this . queueSpan ( span ) ;
2831 return span ;
2932 }
3033
31- public traced < T > (
34+ public async traced < T > (
3235 name : string ,
3336 fn : ( ) => Promise < T > ,
3437 parentSpanId ?: string ,
3538 ) : Promise < T > {
3639 const spanId = this . startSpan ( name , parentSpanId ) ;
37- return fn ( )
38- . then ( ( result ) => {
39- this . endSpan ( spanId ) ;
40- return result ;
41- } )
42- . catch ( ( err ) => {
43- this . endSpan ( spanId ) ;
44- throw err ;
45- } ) ;
40+ return await fn ( ) . finally ( ( ) => this . endSpan ( spanId ) ) ;
4641 }
4742
48- public getActiveSpans ( ) : Span [ ] {
43+ public getActiveSpans ( ) : Array < Span > {
4944 return Array . from ( this . activeSpans . values ( ) ) ;
5045 }
5146
52- public flush ( ) : void {
53- this . saveSpansToFile ( ) ;
54- }
55-
5647 public getTraceJSON ( ) : string {
5748 return JSON . stringify (
5849 this . getActiveSpans ( ) . map ( ( s ) => s . toJSON ( ) ) ,
@@ -61,10 +52,23 @@ export default class Tracer {
6152 ) ;
6253 }
6354
64- private saveSpansToFile ( ) : void {
65- fs . writeFileSync (
66- this . spanFile ,
67- JSON . stringify ( this . getActiveSpans ( ) , null , 2 ) ,
68- ) ;
55+ public endTracing ( ) : void {
56+ this . ended = true ;
57+ }
58+
59+ public async * streamEvents ( ) : AsyncGenerator < Span , void , void > {
60+ while ( true ) {
61+ const value = this . queue . shift ( ) ;
62+ if ( value == null ) {
63+ if ( this . ended ) break ;
64+ await new Promise < void > ( ( resolve ) => {
65+ this . resolveWaitChunksP = resolve ;
66+ } ) ;
67+ continue ;
68+ }
69+ yield value ;
70+ }
6971 }
7072}
73+
74+ export default Tracer ;
0 commit comments