Export `nitroApp` instance
Describe the feature
Context: #3578 (@markthree)
I am currently developing a
zero-downtimeAPI service based on H3 and several Nitro applications. I've found that exporting NitroApps might be more user-friendly, as users may need to access their internal options or perform certain actions (such as invoking shutdown hooks).Example
// plugins/db.ts
// ignore some codes
export default defineNitroPlugin((nitro) => {
nitro.hooks.hook("close", async () => {
const db = await useDB();
db.close();
});
})
// user case
import("./.output/server/index.mjs").then(({ nitroApp }) => {
// ignore some codes
nitroApp.hooks.callHook("close");
})
Additional information
- [ ] Would you be willing to help implement this feature?
@markthree Continuing discussion here before going back to PR.
One first step is to add a new nitroApp.close function. Depending on the hook system, it might be tricky externally. (PR welcome for this)
We should also make sure this feature is available for all (at least server export) presets. We might expose nitro instance to globalThis.nitroApp as one idea.
Just to provide some background context: since this is our local Node API service, I haven't had time to think it through thoroughly.
Currently, I have to build it every time, disconnect the existing service, and then restart it, which is very time-consuming. Moreover, during the disconnection period, my application cannot serve the business.
This led to the idea of developing a zero-downtime API, inspired by unjs/listen. However, during development, I discovered that nitroApp isn't exported. This means I can only extract the database and mount it on globalThis.
Ideally, I'd prefer not to modify the original code extensively. Therefore, I'd like to export nitroApp, but only within the node-middleware preset.
Regarding the second point—mounting nitroApp to globalThis in the preset—this does not seem applicable to my scenario (primarily due to global pollution concerns). As for the first point, I fully agree, but we need to explore how to implement this solution without requiring a destructive update.
Currently, only the node-middleware preset requires nitroApp due to business needs. Other business scenarios might necessitate exporting nitroApp from different server presets, though I haven't identified such cases yet.
Current implementation of nitro runtime, assumes there is one global instance running at a time (even if multiple work by chance we don't have any safe-guards for that).
May i ask why don't you use node cluster for zero downtime swaps? Instances are fully isolated this way yet share same port.
May i ask why don't you use node cluster for zero downtime swaps? Instances are fully isolated this way yet share same port.
Thanks, I'll give this approach a try—it sounds simpler and more efficient. I'm lacking knowledge in this area, I'll need to spend some time thoroughly researching it first.