disposable-mixin

1.0.1 • Public • Published

disposable-mixin

Explicitly releasing resources

Mixin that brings 'Disposable' implementation to your types.

npm version Build Status Coverage Status

    npm install --save disposable-mixin

Motivation

To write types that may free underlying resources explicitly like database connections, sockets and etc. by cleaning the references and invoking nested disposable objects.

Usage

disposable-mixin brings 2 methods:

  • isDisposed returns value which indicates wther the object is already disposed
  • dispose frees specified underlying resources and marks the object as disposed

The mixin comes as a factory function i.e. in order to get mixin it needs to invoke exported function.

    import composeClass from 'compose-class';
    import DisposableMixin from 'disposable-mixin';

    const Class = composeClass({
        mixins: [
            DisposableMixin()
        ]
    });

It is done intentionally in order to be able to pass the list of resource names (keys or symbols) and finalize callback.

    import Symbol from 'es6-symbol';
    import composeClass from 'compose-class';
    import DisposableMixin from 'disposable-mixin';

    const FIELDS = {
        items: Symbol('items')
    };

    const Class = composeClass({
        mixins: [
            DisposableMixin([FIELDS.items])
        ],

        constructor(items) {
            this[FIELDS.items] = items;
        },

        items() {
            return this[FIELDS.items];
        }
    });

    const instance = new Class(createManyObjects());

    console.log(instance.items()); // [Objects...]
    console.log(instance.isDisposed()); // false

    instance.dispose();

    console.log(instance.items()); // null
    console.log(instance.isDisposed()); // true

Finalize callback allows to handle more complex scenarios like calling 'close' methods on database connections, destroy native objects and etc.

// connection.js
    import Symbol from 'es6-symbol';
    import _ from 'lodash';
    import composeClass from 'compose-class';
    import DisposableMixin from 'disposable-mixin';
    import { MongoClient } from 'mongodb';

    const FIELDS = {
        settings: Symbol('settings'),
        connection: Symbol('connection')
    };

    function finalize(instance) {
        if (instance[FIELDS.connection]) {
            instance.close();
        }
    }

    const ConnectionWrapper = composeClass({
        mixins: [
            DisposableMixin(_.values(FIELDS), finalize)
        ],

        constructor(settings) {
            this[FIELDS.settings] = settings;
        },

        open(cb) {
            if (this[FIELDS.connection]) {
                return process.nextTick(() => cb(null));
            }

            return MongoClient.connect(this[FIELDS.settings], (err, db) => {
                if (err) {
                    return cb(err);
                }

                this[FIELDS.connection] = db;

                return cb(null);
            });
        },

        collection(name) {
            return this[FIELDS.connection].collection(name);
        },

        close() {
            if (this[FIELDS.connection]) {
                this[FIELDS.connection].close();
            }
        }
    });

If a resource implements 'Disposable' interface, its dispose methods will be invoked.

// repository.js

import Symbol from 'es6-symbol';
import _ from 'lodash';
import composeClass from 'compose-class';
import DisposableMixin from 'disposable-mixin';
import { MongoClient } from 'mongodb';

const FIELDS = {
    connection: Symbol('connection')
};

const Repository = composeClass({
    mixins: [
        DisposableMixin(_.values(FIELDS))
    ],

    constructor(connection) {
        this[FIELDS.connection] = connection;
    },

    findAll(cb) {
        const cursor = this[FIELDS.connection].collection('restaurants').find();
        cursor.each(cb);

        return this;
    }
});

If we call dispose method of the repository instance, connection will be disposed automatically. Therefore, we can easily build deeply nested objects without worring about possible memory leaks.

/disposable-mixin/

    Package Sidebar

    Install

    npm i disposable-mixin

    Weekly Downloads

    6

    Version

    1.0.1

    License

    MIT

    Last publish

    Collaborators

    • ziflex