Tuesday, February 28, 2023

Coding Challenge #11 Job Scheduler

Daily Coding Challenge #10

Goal: Make a job scheduler that calls function Fn after T miliseconds

// Part 1 / 2 just the simple delayed function call
// JavaScript
function procrastinate(fn, delay){
    setTimeout(fn, delay);
}
procrastinate(()=>{console.log('hi');}, 1000);

// C++
void procrastinate(void*(*fn)(void), int delay){
    Sleep(delay);
    fn();
}
void hi(){
    cout << "hi" << endl;
}
procrastinate((void*(*)(void))hi, 1000);



// Part 2 / 2 full JavaScript scheduler
// interact with it: call sched.start() to start regular checks.
// call sched.register(fn, delay) to add an event
// call sched.stop() if you want it to stop for any reason
// it checks at a user-definable interval
// it executes all events that are scheduled for that moment or prior one time
// you can also schedule it to stop using its own sched.register()

// Note to self: setTimeout,etc make call the function in isolation, where 'this' in the function's body is not defined. To get around this, we pass the object's saved reference to itself ('me') to check(me) each time it is called. And instead of using 'this', we use 'me' to access its properties.
// Note 2: to pass args to a function called by setTimeout, put the args to the called function after the functionToCall and delayToCall. setTImeout(urFn, delayUntilItsCalled, urFnsArg1, urFnsArg2, ...). Each check(me) must pass 'me' again in the next setTimeout() call.

function scheduledEvent(fn, time){
    this.fn = fn;
    this.time = time;
}
function Scheduler(checkInterval){
    this.schedule = [];
    this.checkInterval = checkInterval == undefined ? 1000 : checkInterval;
    this.shouldStop = false;
    this.me = this;
    this.start = function(){
        this.check(this.me);
    }
    this.register = function(fn, delay){ // delay in miliseconds
        this.schedule.push(new scheduledEvent(fn, (new Date()).valueOf() + delay));
        this.schedule.sort((a,b)=>{return a.time > b.time}); // sort from nearest to furthest (smallest time value is at lowest index)
    }
    this.check = function(me){
        var now = (new Date()).valueOf();
        while(me.schedule.length > 0 && now >= me.schedule[0].time){
            me.schedule[0].fn(); // call the function
            me.schedule.splice(0,1); // remove executed scheduledEvent
        }
        if(!me.shouldStop) setTimeout(me.check, me.checkInterval, me);
    }
    this.stop = function(){
        this.shouldStop = true;
    }
}
function test_fn_1(){console.log('i am test_fn_1, hear me rawr :3');}
function test_fn_dos(){console.log('yo soy test_fn_2, dos es dulces xD');}
function test_fn_trois(){console.log('je suis test_fn_3, je suis ton livre');}
function test_fn_si(){console.log('我是test_fn_4。 我的朋友叫我李四。我的朋友是張三和王五。');}
function test_fn_go(){console.log('私の名前はtest_fn_5、五語を話します!');}
function test_fn_kr(){console.log('저는test_fn_6입니다.저것은 체브인입니다!');}
function test_fn_pt(){console.log('Eu sou test_fn_7. Tem leite? Que briga!');}
function test_fn_id(){console.log('test_fn_8, saya juga buku-buku kamu');}
var sched = new Scheduler(1000); // check every second
sched.register(test_fn_1, 1000);
sched.start();
sched.register(test_fn_dos, 2000);
sched.register(test_fn_trois, 3000);
sched.register(test_fn_si, 4000);
sched.register(test_fn_go, 5000);
sched.register(test_fn_kr, 6000);
sched.register(test_fn_pt, 7000);
sched.register(test_fn_id, 8000);
sched.register(()=>{sched.stop();}, 9000); // scheduling stopping the scheduler with its own functions. Have to use a global reference.
sched.register(test_fn_1, 10000); // should not be called. sched should be stopped by now.

No comments:

Post a Comment

Coding Challenge #54 C++ int to std::string (no stringstream or to_string())

Gets a string from an integer (ejemplo gratis: 123 -> "123") Wanted to come up with my own function for this like 10 years ago ...