using concurrent::Futureusing afConcurrent::SynchronizedState** (Service) - Contribute functions to be executed on `Registry` shutdown. ** All functions need to be immutable, which essentially means they can only reference 'const' classes.** Example usage:** ** pre>** class AppModule {** @Contribute { serviceType=RegistryShutdown# }** static Void contributeRegistryShutdown(Configuration conf, MyService myService) {** conf["myShutdownFunc"] = |->| { myService.shutdown() }** }** }** <pre** ** If the shutdown method of your service depends on other services being available, add a constraint on 'afIoc.shutdown': ** ** conf.set("myShutdownFunc", |->| { myService.shutdown() }).before("afIoc.shutdown")** ** Note that Errs thrown by shutdown functions will be logged and then swallowed.** ** @uses Configuration of '|->| []'constmixin RegistryShutdown {internalabstract Void shutdown()}internalconstclass RegistryShutdownImpl : RegistryShutdown {privateconststatic Log log := Utils.getLog(RegistryShutdown#)privateconst OneShotLock lock := OneShotLock(IocMessages.registryShutdown)privateconst Str:|->| shutdownFuncsnew make(Str:|->| shutdownFuncs){ shutdownFuncs.each |val, key| {try val.toImmutablecatchthrow NotImmutableErr(IocMessages.shutdownFuncNotImmutable(key))}this.shutdownFuncs = shutdownFuncs}override Void shutdown(){ lock.check lock.lock shutdownFuncs.each | |->| listener, Str id| {try{ listener.call}catch(Err e){ log.err(IocMessages.shutdownListenerError(id, e))}}}}