using concurrent::Actorusing concurrent::ActorPoolusing concurrent::AtomicRefusing concurrent::AtomicBoolusing web::WebModusing afIocusing afIocConfig::ConfigSource** The `web::WebMod` that runs in [Wisp]`pod:wisp`. constclass BedSheetWebMod : WebMod {privateconststatic Log log := Utils.getLog(BedSheetWebMod#)** Returns 'pod.dis' (or 'proj.name'if not found) from the application's pod meta, or the pod name if neither are defined.const Str appName** The port number this Bed App will be listening on. const Int port** The IoC registry.const Registry registryprivateconst MiddlewarePipeline pipeline** Creates this 'WebMod'. Use a 'BedSheetBuilder' to create the 'Registry' instance - it ensures all the options have been set.new make(Registry registry){ bedServer := (BedSheetServer) registry.activeScope.serviceById(BedSheetServer#.qname)this.registry = registry this.appName = bedServer.appNamethis.port = bedServer.port// BUGFIX: eager load the middleware pipeline, so we can use the ErrMiddleware// otherwise Errs thrown when instantiating middleware end up in limbo// Errs from the FileHandler ctor are a prime examplethis.pipeline = registry.activeScope.serviceById(MiddlewarePipeline#.qname)} @NoDocoverride Void onService(){ req.mod = thistry{ registry.activeScope.createChild("request"){// this is actual call to BedSheet! // the rest of this class is just startup and error handling fluff! pipeline.service}}catch(RegistryShutdownErr err){// nothing we can do hereif(!res.isCommitted) res.sendErr(500, "BedSheet shutting down...")return// theoretically, this should have already been dealt with by our ErrMiddleware...// ...but it's handy for BedSheet development!}catch(Err err){// try to send something to the browser errLog := err.traceToStrtry{ errPrinter := (ErrPrinterStr) registry.activeScope.serviceById(ErrPrinterStr#.qname) errLog = errPrinter.errToStr(err)}catch{}// log and throw, because we don't trust Wisp to log it Env.cur.err.printLine(errLog)if(!res.isCommitted) res.sendErr(500, "${err.typeof} - ${err.msg}")throw err}} @NoDocoverride Void onStart(){// start the destroyer! meta := (RegistryMeta) registry.activeScope.serviceById(RegistryMeta#.qname) beds := (BedSheetServer) registry.activeScope.serviceById(BedSheetServer#.qname)if(meta.options[BsConstants.meta_pingProxy] == true){ pingPort := (Int) meta.options[BsConstants.meta_proxyPort] destroyer := (AppDestroyer) registry.activeScope.build(AppDestroyer#, [ActorPool(), pingPort]) destroyer.start}// print BedSheet connection details configSrc := (ConfigSource) registry.activeScope.serviceByType(ConfigSource#) host := (Uri) configSrc.get(BedSheetConfigIds.host, Uri#) ver := beds.appPod?.version log.info(BsLogMsgs.bedSheetWebMod_started(appName, ver, host))} @NoDocoverride Void onStop(){ registry.shutdown log.info(BsLogMsgs.bedSheetWebMod_stopping(appName))}}