What is the promise disposer pattern?

The issue with your code

The problem with the above approach is that if you forget releasing the connection after every single time you perform getDb you have a resource leak that might freeze your app eventually when it runs out of the resource you’re leaking.

You might, in one place do:

var users = getDb().then(function(conn){
     return conn.query("SELECT name FROM users");
});

Which will leak a database connection that was never closed.


The disposer pattern

The disposer pattern is a way to couple a scope of code with owning the resource. By binding the resource to a scope we make sure it is always released when we’re done with it and we can’t easily forget to release it. It is similar to using in C#, with in Python and try-with-resource in Java as well as RAII in C++.

It looks like:

 withResource(function(resource){
     return fnThatDoesWorkWithResource(resource); // returns a promise
 }).then(function(result){
    // resource disposed here
 });

Applying it here

If we wrote our code as:

function withDb(work){
    var _db;
    return myDbDriver.getConnection().then(function(db){
        _db = db; // keep reference 
        return work(db); // perform work on db
    }).finally(function(){
        if (_db)
            _db.release();
    });
}

We could write our above code as:

 withDb(function(conn){
     return conn.query("SELECT name FROM users");
 }).then(function(users){
     // connection released here
 });

Examples of users of the disposer pattern are sequelize and knex (bookshelf’s query builder). It’s also possible to use it for simpler things like hiding a loader when all AJAX requests completed for instance.

Leave a Comment