Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

PATCH: API to put maximum time limit on timers/intervals

#101

Loading a page that uses setIntervals never returns control or might return control after really long time. For instance, try loading my dorky website http://client9.com/ for instance. The "blinking cursor" is done by a js setInternal that repeats forever.

It would be nice to have some API to set a maximum time limit on "how long the page runs".

Not sure I completely understand how the source code is laid out, but the following patch basically does:

If there is another event/interval
and If Env.maxTime is defined and > 0
and if the now() + interval is past Env.maxTime
then exit

Problems:

  • No nice way of reseting "when the page started" (could be hacked with $timers.first = Date.now())
  • $timers.first is set when env.rhino.js is loaded, NOT when document is fully loaded.
  • I doubt "maxTime" is the best name, and a default could be added to plaform/core.js as well.

Thoughts? Or should I use the group for this type of stuff?

+++ b/src/timer/timer.js
@@ -10,6 +10,7 @@ var $timers = [],
 $timers.lock = function(fn){
     Envjs.sync(fn)();
 };
+$timers.first = Date.now();
 
 //private internal class
 var Timer = function(fn, interval){
@@ -169,6 +170,13 @@ Envjs.wait = function(wait) {
                 }
             }
         });
+
+       // exit if next event occurs past the maximum allowed time (if any)
+       if (earliest && Envjs && Envjs.maxTime > 0 && (earliest.at >= ($timers.first + Envjs.maxTime))) {
+           EVENT_LOOP_RUNNING = false;
+           return;
+       }
+
         //next sleep time
         sleep = earliest && earliest.at - Date.now();
         if ( earliest && sleep <= 0 ) {

Reported by nickg · March 5th, 2010 @ 07:17 PM

State: open
Milestone: none
Assigned to: nickg nickg

Activity

  1. Steven Parkes
    Steven Parkes

    I think the event loop already has this functionality, in that wait can be called with a maximum amount of time to wait. The bigger issue then is how to get the overall driver which is calling wait to call the event loop with a value. Right now, I believe it always calls it with no value which means 'wait forever'.

    March 10th, 2010 @ 06:28 AM

  2. nickg
    nickg

    Hi Steve,

    I think you are right about the event loop. The problem is the "README" says the caller (you), is suppose to manually call Envjs.wait() after the initial parse. Unfortunately, Envjs.wait() is in the code in a few places. Maybe they should be pulled out.

    Hmmm.....

    -nickg

    March 15th, 2010 @ 12:24 PM

  3. Steven Parkes
    Steven Parkes

    There are a couple of places where there are waits to support the parser, which does some things async (in order to support document.write). Those generally call wait with a -1 parameter.

    There are a couple of new places in the 1.2 code base that call wait w/o that parameter, which with the 1.1 timer, would cause an unending wait if any intervals or infinitely rescheduled timers were been set. But I'm not too familiar with the 1.2 changes.

    The async nature of the parser has been a bit of a challenge: it has a lot of corner cases, a number of which we haven't hit, I suspect.

    March 15th, 2010 @ 12:44 PM

  4. nickg
    nickg

    Hi again,

    I don't know if it's your domain or not, but you might find ticket 107 interesting:
    http://envjs.lighthouseapp.com/projects/21590/tickets/107-on-page-w...

    Also, can one set a flag to make the parser synchronous? In my app, I don't need the async, and might make the app a bit more straightforward?

    thanks!

    --nickg

    March 15th, 2010 @ 12:53 PM

  5. Steven Parkes
    Steven Parkes

    There's code that makes the parser sync to handle innerHTML, which can't have script tags and so can't do document.write.

    As far as I know, there's no way to set that externally.

    Might not be a good idea though ... the parser's tricky, so if there are other ways to achieve what's needed, they might be better.

    March 15th, 2010 @ 01:11 PM

  6. nickg
    nickg

    Ok this gives me some ideas on how to make global timeout really easy.

    Seem like it might be as simple as replacing

    Envjs.wait();
    

    with

    Envjs.wait(Envjs.MAXTIMEOUT_OR_SOMETHING);
    

    If it doesn't exist, then it's the same behavior. If it does, then use it.

    I'll play around and report back.

    March 15th, 2010 @ 01:14 PM

  7. nickg
    nickg
    • State changed from new to open
    • Assigned user set to nickg
    • Title changed from API to put maximum time limit on timers/intervals (patch) to PATHC: API to put maximum time limit on timers/intervals

    Turns out actually is easy, with almost no code change (again thanks to the groundwork already laid -- thank you). This is the spot to change.

    var __exchangeHTMLDocument__ = function(doc, text, url){
        var html, head, title, body, event;
        try{
            doc.baseURI = url;
            HTMLParser.parseDocument(text, doc);
            var t0 = Date.now();  // ignore
            Envjs.wait(1000);   <---------------------- HERE
            var t1 = Date.now();  // ignore
            console.log("Post Parse MS: %d", (t1-t0));  // ignore
        }catch(e){
    

    Any thoughts on the constant to use? Envjs.TIMER_MAX_ELASPED and what if any default value should be used?

    thanks all,

    --nickg

    March 21st, 2010 @ 02:47 PM

  8. nickg
    nickg
    • Title changed from PATHC: API to put maximum time limit on timers/intervals to PATCH: API to put maximum time limit on timers/intervals

    March 21st, 2010 @ 02:48 PM

  9. Steven Parkes
    Steven Parkes
    • Tag cleared.

    Can you try changing the wait() to wait(-1)?

    This got changed very early in the refactor, so there's no history in git. I'm not sure if there was a problem that was happening that dropping the argument helped or if it was inadvertent.

    The reason wait accepts negative arguments is just for this case ... I'd like to at least try to get it back in. If something's broke, I can try to fix it.

    March 21st, 2010 @ 05:02 PM

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.