1
- import { assert , details as X } from '@agoric/assert' ;
1
+ import { assert , details as X , quote } from '@agoric/assert' ;
2
2
3
3
const IDLE = 'idle' ;
4
4
const STARTUP = 'startup' ;
5
5
const DELIVERY = 'delivery' ;
6
6
7
- export function makeDummySlogger ( makeConsole ) {
7
+ function makeCallbackRegistry ( callbacks ) {
8
+ const todo = new Set ( Object . keys ( callbacks ) ) ;
8
9
return harden ( {
9
- addVat : ( ) => 0 ,
10
- vatConsole : ( ) => makeConsole ( 'disabled slogger' ) ,
11
- startup : ( ) => ( ) => 0 , // returns nop finish() function
12
- delivery : ( ) => ( ) => 0 ,
13
- syscall : ( ) => ( ) => 0 ,
14
- changeCList : ( ) => ( ) => 0 ,
15
- terminateVat : ( ) => ( ) => 0 ,
10
+ /**
11
+ * Robustly wrap a method with a callbacks[method] function, if defined. We
12
+ * incur no runtime overhead if the given callback method isn't defined.
13
+ *
14
+ * @param {string } method wrap with callbacks[method]
15
+ * @param {(...args: Array<unknown>) => unknown } impl the original
16
+ * implementation of the method
17
+ * @returns {(...args: Array<unknown>) => unknown } the wrapped method if the
18
+ * callback is defined, or original method if not
19
+ */
20
+ registerCallback ( method , impl ) {
21
+ todo . delete ( method ) ;
22
+ const cb = callbacks [ method ] ;
23
+ if ( ! cb ) {
24
+ // No registered callback, just use the implementation directly.
25
+ console . error ( 'no registered callback for' , method ) ;
26
+ return impl ;
27
+ }
28
+
29
+ return ( ...args ) => {
30
+ // Invoke the implementation first.
31
+ const ret = impl ( ...args ) ;
32
+ try {
33
+ // Allow the callback to observe the call synchronously, and affect
34
+ // the finisher function, but not to throw an exception.
35
+ const cbRet = cb ( method , args , ret ) ;
36
+ if ( typeof ret === 'function' ) {
37
+ // We wrap the finisher in the callback's return value.
38
+ return ( ...finishArgs ) => {
39
+ try {
40
+ return cbRet ( ...finishArgs ) ;
41
+ } catch ( e ) {
42
+ console . error (
43
+ `failed to call registered ${ method } .finish function:` ,
44
+ e ,
45
+ ) ;
46
+ }
47
+ return ret ( ...args ) ;
48
+ } ;
49
+ }
50
+ // We just return the callback's return value.
51
+ return cbRet ;
52
+ } catch ( e ) {
53
+ console . error ( 'failed to call registered' , method , 'callback:' , e ) ;
54
+ }
55
+ return ret ;
56
+ } ;
57
+ } ,
58
+ /**
59
+ * Declare that all the methods have been registered.
60
+ *
61
+ * @param {string } errorUnusedMsg message to display if there are callback
62
+ * names that don't correspond to a registration
63
+ */
64
+ doneRegistering ( errorUnusedMsg = `Unrecognized callback names:` ) {
65
+ const cbNames = [ ...todo . keys ( ) ] ;
66
+ if ( ! cbNames . length ) {
67
+ return ;
68
+ }
69
+ console . warn (
70
+ errorUnusedMsg ,
71
+ cbNames
72
+ . map ( quote )
73
+ . sort ( )
74
+ . join ( ', ' ) ,
75
+ ) ;
76
+ } ,
16
77
} ) ;
17
78
}
18
79
19
- export function makeSlogger ( writeObj ) {
80
+ export function makeDummySlogger ( slogCallbacks , makeConsole ) {
81
+ const { registerCallback : reg , doneRegistering } = makeCallbackRegistry (
82
+ slogCallbacks ,
83
+ ) ;
84
+ const dummySlogger = harden ( {
85
+ addVat : reg ( 'addVat' , ( ) => 0 ) ,
86
+ vatConsole : reg ( 'vatConsole' , ( ) => makeConsole ( 'disabled slogger' ) ) ,
87
+ startup : reg ( 'startup' , ( ) => ( ) => 0 ) , // returns nop finish() function
88
+ delivery : reg ( 'delivery' , ( ) => ( ) => 0 ) ,
89
+ syscall : reg ( 'syscall' , ( ) => ( ) => 0 ) ,
90
+ changeCList : reg ( 'changeCList' , ( ) => ( ) => 0 ) ,
91
+ terminateVat : reg ( 'terminateVat' , ( ) => ( ) => 0 ) ,
92
+ } ) ;
93
+ doneRegistering ( `Unrecognized makeDummySlogger slogCallbacks names:` ) ;
94
+ return dummySlogger ;
95
+ }
96
+
97
+ export function makeSlogger ( slogCallbacks , writeObj ) {
20
98
const write = writeObj ? e => writeObj ( e ) : ( ) => 0 ;
21
99
22
100
const vatSlogs = new Map ( ) ; // vatID -> vatSlog
@@ -28,7 +106,7 @@ export function makeSlogger(writeObj) {
28
106
let syscallNum ;
29
107
30
108
function assertOldState ( exp , msg ) {
31
- assert ( state === exp , X `vat ${ vatID } in ${ state } , not ${ exp } : ${ msg } ` ) ;
109
+ assert . equal ( state , exp , X `vat ${ vatID } in ${ state } , not ${ exp } : ${ msg } ` ) ;
32
110
}
33
111
34
112
function vatConsole ( origConsole ) {
@@ -65,9 +143,9 @@ export function makeSlogger(writeObj) {
65
143
syscallNum = 0 ;
66
144
67
145
// dr: deliveryResult
68
- function finish ( dr ) {
146
+ function finish ( dr , stats ) {
69
147
assertOldState ( DELIVERY , 'delivery-finish called twice?' ) ;
70
- write ( { type : 'deliver-result' , ...when , dr } ) ;
148
+ write ( { type : 'deliver-result' , ...when , dr, stats } ) ;
71
149
state = IDLE ;
72
150
}
73
151
return harden ( finish ) ;
@@ -126,13 +204,30 @@ export function makeSlogger(writeObj) {
126
204
// write({ type: 'annotate-vat', vatID, data });
127
205
// }
128
206
129
- return harden ( {
130
- addVat,
131
- vatConsole : ( vatID , ...args ) => vatSlogs . get ( vatID ) . vatConsole ( ...args ) ,
132
- startup : ( vatID , ...args ) => vatSlogs . get ( vatID ) . startup ( ...args ) ,
133
- delivery : ( vatID , ...args ) => vatSlogs . get ( vatID ) . delivery ( ...args ) ,
134
- syscall : ( vatID , ...args ) => vatSlogs . get ( vatID ) . syscall ( ...args ) ,
135
- changeCList : ( vatID , ...args ) => vatSlogs . get ( vatID ) . changeCList ( ...args ) ,
136
- terminateVat : ( vatID , ...args ) => vatSlogs . get ( vatID ) . terminateVat ( ...args ) ,
207
+ const { registerCallback : reg , doneRegistering } = makeCallbackRegistry (
208
+ slogCallbacks ,
209
+ ) ;
210
+ const slogger = harden ( {
211
+ addVat : reg ( 'addVat' , addVat ) ,
212
+ vatConsole : reg ( 'vatConsole' , ( vatID , ...args ) =>
213
+ vatSlogs . get ( vatID ) . vatConsole ( ...args ) ,
214
+ ) ,
215
+ startup : reg ( 'startup' , ( vatID , ...args ) =>
216
+ vatSlogs . get ( vatID ) . startup ( ...args ) ,
217
+ ) ,
218
+ delivery : reg ( 'delivery' , ( vatID , ...args ) =>
219
+ vatSlogs . get ( vatID ) . delivery ( ...args ) ,
220
+ ) ,
221
+ syscall : reg ( 'syscall' , ( vatID , ...args ) =>
222
+ vatSlogs . get ( vatID ) . syscall ( ...args ) ,
223
+ ) ,
224
+ changeCList : reg ( 'changeCList' , ( vatID , ...args ) =>
225
+ vatSlogs . get ( vatID ) . changeCList ( ...args ) ,
226
+ ) ,
227
+ terminateVat : reg ( 'terminateVat' , ( vatID , ...args ) =>
228
+ vatSlogs . get ( vatID ) . terminateVat ( ...args ) ,
229
+ ) ,
137
230
} ) ;
231
+ doneRegistering ( `Unrecognized makeSlogger slogCallbacks names:` ) ;
232
+ return slogger ;
138
233
}
0 commit comments