tim-kos/node-retry

new method retry.wrap

kof opened this issue · 10 comments

kof commented

I am often writing the same stuff over and over, this function would reduce a lot, but it is only possible to implement it based on 2 conventions:
- callback is always the last argument
- err is always the first argument

So basically I want to say: wrap all functions of object obj into retry logic, use opts for retry options, optionally props is a list of props I need to wrap, otherwise wrap all functions.

retry.wrap(opts, obj, props)

Would you accept a pull request implementing this?

Hey kof,

please explain "all functions of object obj". Shouldn't this be an array of functions? Or maybe I am not getting the big picture.

kof commented
// wrap all methods of myLibrary object
retry.wrap({retries: 3}, myLibrary);
// wrap only named methods of myLibrary object
retry.wrap({retries: 3}, myLibrary, ['method1', 'method2', 'method3']);
kof commented

even better

// wrap all mehtods of myLibrary using default options
retry.wrap(myLibrary);

// wrap all methods of myLibrary object
retry.wrap(myLibrary, {retries: 3});

// wrap only named methods of myLibrary object
retry.wrap(myLibrary, {retries: 3}, ['method1', 'method2', 'method3']);
kof commented
function wrap(obj, options, methods) {
    if (options instanceof Array) {
        methods = options;
        options = null;
    }

    if (!methods) {
        methods = Object.keys(obj);
    }

    methods.forEach(function(method) {
        var origin = obj[method];

        if (typeof origin != 'function') {
            return;
        }

        obj[method] = function() {
            var op = retry.operation(options),
                args = Array.prototype.slice.call(arguments),
                callback = args.pop();

            args.push(function(err) {
                if (op.retry(err)) {
                    return;
                }
                if (err) {
                    arguments[0] = op.mainError();
                }
                callback.apply(this, arguments);
            });

            op.attempt(function() {
                origin.apply(obj, args);
            });
        };
    });    
}
kof commented

It needs some changes to support all browsers ... but basically thats it.

I see. Pretty interesting.

If you could also write some tests for it I'd merge a PR for this one.

kof commented

What are requirements for the environment? Is this module supposed to be used in browser? Or just node?

For now it's just supposed to be used out of node, but I am sure it can be used easily in the browser with node-browserify.

Will finish this and merge the related PR.