sp9usb/sleep-async

Expose the interval parameter please

davyboyhayes opened this issue · 2 comments

I have a long running process whereby I run a task that will take upwards of 30 minutes to complete (uploading content to a server, and 30 minutes later it is replicated to our CDN). I would like to not poll every 10ms, but once every minute. I can code around this by exposing a time condition as well as an availability condition in the test, but this would be easier if I could specify the interval manually. It would mean my grunt process would run less CPU in the downtime.

Many thanks,

David

Hello!

Thank You for question. I've added functionality that solves your problem. Please upgrade to 1.0.1 version.

Regards,
Kamil

That's great thanks. When I was developing using this, I actually found I needed to go deeper still. The problem I had was that the check I needed for the condition, was not going to return in the same thread as the call to the condition function. In my case, I was issuing a http request, that would at some time down the line return either a 200 or 404, and my condition would detect the presence of a 200. I had to modify the sleep async to use this notion of the condition having a callback.

// borrowed and altered from https://github.com/kamil4521/sleep-async/blob/master/sleep-async.js
var sleepConditionHasCallback = function(timeout, condition, conditionContext, conditionParams, interval, callback, callbackContext, callbackParams){
    var callee = arguments.callee;
    var calleeArgs = arguments;
    var startTimeInMilisecond = new Date().getTime();
    setTimeout(function(){
        var totalTimeHasExpired = ((startTimeInMilisecond + timeout) < (new Date().getTime()))
        var conditionCallback = function(totalTimeHasExpiredOrConditionIsTrue) {
            if (totalTimeHasExpiredOrConditionIsTrue) {
                callback.apply(callbackContext, callbackParams);
            } else {
                setTimeout(function() {callee.apply(callbackContext, calleeArgs)}, interval);
            }
        };
        if (totalTimeHasExpired) {
            conditionCallback(totalTimeHasExpired);
        } else {
            var params = conditionParams.slice();
            params.push(conditionCallback);
            condition.apply(conditionContext, params);
        }
    }, interval);
};

This is a lot uglier, and requires stuffing a LOT more parameters, but, this allows me the ability to provide a set of parameters to the condition, and callback function. The requisites are that:

  • The conditionParams object must be an array (can be an empty array)
  • The condition must expect conditionParams.length + 1 parameters, where the last parameter is the function to call with one parameter of true or false, when the condition has been calculated
  • The condition must call the last parameter as a function, passing in true or false, depending upon whether the condition is true or false.
  • The callbackParams object must be an array (can be an empty array)
  • The callback function should expect callbackParams.length parameters, but that is outwith the care of this function.

A typical use case would be:

sleepConditionHasCallback(3600000, function(firstParam, secondParam, callback) {
   console.log(firstParam, secondParam);
   $.ajax(firstParam + secondParam).done(function(data) {
      callback(true);
   }).fail(function(error) {
      callback(false);
   });
}, this, ['http:', '//myserver.com/api'], 60000, function(a, b) {
   console.log(a, b);
}, this, ['something', 'somethingElse']);