github.com/bananabytelabs/wazero@v0.0.0-20240105073314-54b22a776da8/experimental/close.go (about) 1 package experimental 2 3 import ( 4 "context" 5 6 "github.com/bananabytelabs/wazero/internal/close" 7 ) 8 9 // CloseNotifier is a notification hook, invoked when a module is closed. 10 // 11 // Note: This is experimental progress towards #1197, and likely to change. Do 12 // not expose this in shared libraries as it can cause version locks. 13 type CloseNotifier interface { 14 // CloseNotify is a notification that occurs *before* an api.Module is 15 // closed. `exitCode` is zero on success or in the case there was no exit 16 // code. 17 // 18 // Notes: 19 // - This does not return an error because the module will be closed 20 // unconditionally. 21 // - Do not panic from this function as it doing so could cause resource 22 // leaks. 23 // - While this is only called once per module, if configured for 24 // multiple modules, it will be called for each, e.g. on runtime close. 25 CloseNotify(ctx context.Context, exitCode uint32) 26 } 27 28 // ^-- Note: This might need to be a part of the listener or become a part of 29 // host state implementation. For example, if this is used to implement state 30 // cleanup for host modules, possibly something like below would be better, as 31 // it could be implemented in a way that allows concurrent module use. 32 // 33 // // key is like a context key, stateFactory is invoked per instantiate and 34 // // is associated with the key (exposed as `Module.State` similar to go 35 // // context). Using a key is better than the module name because we can 36 // // de-dupe it for host modules that can be instantiated into different 37 // // names. Also, you can make the key package private. 38 // HostModuleBuilder.WithState(key any, stateFactory func() Cleanup)` 39 // 40 // Such a design could work to isolate state only needed for wasip1, for 41 // example the dirent cache. However, if end users use this for different 42 // things, we may need separate designs. 43 // 44 // In summary, the purpose of this iteration is to identify projects that 45 // would use something like this, and then we can figure out which way it 46 // should go. 47 48 // CloseNotifyFunc is a convenience for defining inlining a CloseNotifier. 49 type CloseNotifyFunc func(ctx context.Context, exitCode uint32) 50 51 // CloseNotify implements CloseNotifier.CloseNotify. 52 func (f CloseNotifyFunc) CloseNotify(ctx context.Context, exitCode uint32) { 53 f(ctx, exitCode) 54 } 55 56 // WithCloseNotifier registers the given CloseNotifier into the given 57 // context.Context. 58 func WithCloseNotifier(ctx context.Context, notifier CloseNotifier) context.Context { 59 if notifier != nil { 60 return context.WithValue(ctx, close.NotifierKey{}, notifier) 61 } 62 return ctx 63 }