Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disposer support #48

Closed
jeffijoe opened this issue Nov 11, 2017 · 3 comments
Closed

Disposer support #48

jeffijoe opened this issue Nov 11, 2017 · 3 comments
Assignees
Milestone

Comments

@jeffijoe
Copy link
Owner

jeffijoe commented Nov 11, 2017

Proposal

Support disposing dependencies.

Each resolver (registration) can specify a disposer function to call when container.dispose() is called.

Motivation

This is useful for managing dependencies that have resources to dispose—connection pools for example.

In test runners like Jest, watch-mode will recycle worker processes which means connections may or may not have been closed between each run. In testing HTTP servers, It is a good practice to call server.close() after the tests are done.

We want to be able to run cleanup on dependencies in the same way. For example:

server.on('close', () => container.dispose())

Proposed API

  • Introduce container.dispose()
  • Introduce disposer option for asClass and asFunction resolvers
  • Disposing a container also disposes it's child (scoped) containers
  • Containers are disposed bottom-first; this means scoped containers are disposed before their parent.
  • Only SCOPED and SINGLETON registrations can be disposed as they are the only ones the container caches.

Example

const pg = require('pg')
const { createContainer, asFunction } = require('awilix')
const container = createContainer()
  .register({
    pool: (
      asFunction(() => new pg.Pool({ ... }))
        .singleton()
        .disposer((pool) => pool.end())
    )
  })

// .. later, but only if a `pool` was ever created
container.dispose().then(() => {
  console.log('One disposable connection.. disposed! Huehehehe')
})
@jeffijoe jeffijoe self-assigned this Nov 11, 2017
@jeffijoe jeffijoe added this to the v3 milestone Nov 11, 2017
@cikasfm
Copy link

cikasfm commented Nov 13, 2017

+1 Yes, please!

@Seldszar
Copy link
Contributor

Seldszar commented Nov 17, 2017

Would it be possible to make disposers async?
Like waiting a disconnection before completing the disposal.

An example with Discord.js:

const Discord = require('discord.js')
const { createContainer, asFunction } = require('awilix')
const container = createContainer()
  .register({
    client: (
      asFunction(() => new Discord.Client({ ... }))
        .disposer((client) => client.destroy()) // Destroy is an async method in this case
    )
  })

// .. later
container.dispose()
  .then(() => {
    console.log('Client destroyed')
  })

@jeffijoe
Copy link
Owner Author

@Seldszar yeah, I was thinking that as well. 😀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants