Fossil SCM
Replace an a recurrent setInterval() timer in /chat's poll-connection error handler with a single-fire-as-needed setTimeout(). This saves some CPU and allows /chat to respond more quickly to non-timeout HTTP errors.
Commit
1bfb06c7524b132a4458d014cc1dace02198873483f960e9b79f9f30ecbefe33
Parent
e8bbaf924f97764…
1 file changed
+29
-32
+29
-32
| --- src/fossil.page.chat.js | ||
| +++ src/fossil.page.chat.js | ||
| @@ -2732,42 +2732,38 @@ | ||
| 2732 | 2732 | if(true===f.isFirstCall){ |
| 2733 | 2733 | f.isFirstCall = false; |
| 2734 | 2734 | Chat.pendingOnError = undefined; |
| 2735 | 2735 | Chat.ajaxStart(); |
| 2736 | 2736 | Chat.e.viewMessages.classList.add('loading'); |
| 2737 | - if(1) setInterval( | |
| 2738 | - /* | |
| 2739 | - We manager onerror() results in poll() using a | |
| 2740 | - stack of error objects and we delay their handling by | |
| 2741 | - a small amount, rather than immediately when the | |
| 2742 | - exception arrives. | |
| 2743 | - | |
| 2744 | - This level of indirection is necessary to be able to | |
| 2745 | - unambiguously identify client-timeout-specific polling | |
| 2746 | - errors from other errors. Timeouts are always announced in | |
| 2747 | - pairs of an HTTP 0 and something we can unambiguously | |
| 2748 | - identify as a timeout. When we receive an HTTP 0 we put it | |
| 2749 | - into this queue. If an ontimeout() call arrives before this | |
| 2750 | - error is handled, this error is removed from the stack. If, | |
| 2751 | - however, an HTTP 0 is seen in this stack without an | |
| 2752 | - accompanying timeout, we handle it from here. | |
| 2753 | - | |
| 2754 | - It's kinda like in the curses C API, where you to match | |
| 2755 | - ALT-X by first getting an ESC event, then an X event, but | |
| 2756 | - this one is a lot less explicable. (It's almost certainly a | |
| 2757 | - mis-handling bug in F.fetch(), but it has so far eluded my | |
| 2758 | - eyes.) | |
| 2759 | - */ | |
| 2760 | - ()=>{ | |
| 2761 | - if( Chat.pendingOnError ){ | |
| 2762 | - const x = Chat.pendingOnError; | |
| 2763 | - Chat.pendingOnError = undefined; | |
| 2764 | - afterPollFetch(x); | |
| 2765 | - } | |
| 2766 | - }, | |
| 2767 | - 1000 | |
| 2768 | - ); | |
| 2737 | + /* | |
| 2738 | + We manager onerror() results in poll() in a roundabout | |
| 2739 | + manner: when an onerror() arrives, we stash it aside | |
| 2740 | + for a moment before processing it. | |
| 2741 | + | |
| 2742 | + This level of indirection is necessary to be able to | |
| 2743 | + unambiguously identify client-timeout-specific polling errors | |
| 2744 | + from other errors. Timeouts are always announced in pairs of | |
| 2745 | + an HTTP 0 and something we can unambiguously identify as a | |
| 2746 | + timeout (in that order). When we receive an HTTP error we put | |
| 2747 | + it into this queue. If an ontimeout() call arrives before | |
| 2748 | + this error is handled, this error is ignored. If, however, an | |
| 2749 | + HTTP error is seen without an accompanying timeout, we handle | |
| 2750 | + it from here. | |
| 2751 | + | |
| 2752 | + It's kinda like in the curses C API, where you to match | |
| 2753 | + ALT-X by first getting an ESC event, then an X event, but | |
| 2754 | + this one is a lot less explicable. (It's almost certainly a | |
| 2755 | + mis-handling bug in F.fetch(), but it has so far eluded my | |
| 2756 | + eyes.) | |
| 2757 | + */ | |
| 2758 | + f.delayPendingOnError = function(err){ | |
| 2759 | + if( Chat.pendingOnError ){ | |
| 2760 | + const x = Chat.pendingOnError; | |
| 2761 | + Chat.pendingOnError = undefined; | |
| 2762 | + afterPollFetch(x); | |
| 2763 | + } | |
| 2764 | + }; | |
| 2769 | 2765 | } |
| 2770 | 2766 | let nErr = 0; |
| 2771 | 2767 | F.fetch("chat-poll",{ |
| 2772 | 2768 | timeout: Chat.timer.pollTimeout, |
| 2773 | 2769 | urlParams:{ |
| @@ -2787,10 +2783,11 @@ | ||
| 2787 | 2783 | Chat._isBatchLoading = false; |
| 2788 | 2784 | if(Chat.beVerbose){ |
| 2789 | 2785 | console.error("poll.onerror:",err.name,err.status,JSON.stringify(err)); |
| 2790 | 2786 | } |
| 2791 | 2787 | Chat.pendingOnError = err; |
| 2788 | + setTimeout(f.delayPendingOnError, 250); | |
| 2792 | 2789 | }, |
| 2793 | 2790 | onload:function(y){ |
| 2794 | 2791 | reportConnectionOkay('poll.onload', true); |
| 2795 | 2792 | newcontent(y); |
| 2796 | 2793 | if(Chat._isBatchLoading){ |
| 2797 | 2794 |
| --- src/fossil.page.chat.js | |
| +++ src/fossil.page.chat.js | |
| @@ -2732,42 +2732,38 @@ | |
| 2732 | if(true===f.isFirstCall){ |
| 2733 | f.isFirstCall = false; |
| 2734 | Chat.pendingOnError = undefined; |
| 2735 | Chat.ajaxStart(); |
| 2736 | Chat.e.viewMessages.classList.add('loading'); |
| 2737 | if(1) setInterval( |
| 2738 | /* |
| 2739 | We manager onerror() results in poll() using a |
| 2740 | stack of error objects and we delay their handling by |
| 2741 | a small amount, rather than immediately when the |
| 2742 | exception arrives. |
| 2743 | |
| 2744 | This level of indirection is necessary to be able to |
| 2745 | unambiguously identify client-timeout-specific polling |
| 2746 | errors from other errors. Timeouts are always announced in |
| 2747 | pairs of an HTTP 0 and something we can unambiguously |
| 2748 | identify as a timeout. When we receive an HTTP 0 we put it |
| 2749 | into this queue. If an ontimeout() call arrives before this |
| 2750 | error is handled, this error is removed from the stack. If, |
| 2751 | however, an HTTP 0 is seen in this stack without an |
| 2752 | accompanying timeout, we handle it from here. |
| 2753 | |
| 2754 | It's kinda like in the curses C API, where you to match |
| 2755 | ALT-X by first getting an ESC event, then an X event, but |
| 2756 | this one is a lot less explicable. (It's almost certainly a |
| 2757 | mis-handling bug in F.fetch(), but it has so far eluded my |
| 2758 | eyes.) |
| 2759 | */ |
| 2760 | ()=>{ |
| 2761 | if( Chat.pendingOnError ){ |
| 2762 | const x = Chat.pendingOnError; |
| 2763 | Chat.pendingOnError = undefined; |
| 2764 | afterPollFetch(x); |
| 2765 | } |
| 2766 | }, |
| 2767 | 1000 |
| 2768 | ); |
| 2769 | } |
| 2770 | let nErr = 0; |
| 2771 | F.fetch("chat-poll",{ |
| 2772 | timeout: Chat.timer.pollTimeout, |
| 2773 | urlParams:{ |
| @@ -2787,10 +2783,11 @@ | |
| 2787 | Chat._isBatchLoading = false; |
| 2788 | if(Chat.beVerbose){ |
| 2789 | console.error("poll.onerror:",err.name,err.status,JSON.stringify(err)); |
| 2790 | } |
| 2791 | Chat.pendingOnError = err; |
| 2792 | }, |
| 2793 | onload:function(y){ |
| 2794 | reportConnectionOkay('poll.onload', true); |
| 2795 | newcontent(y); |
| 2796 | if(Chat._isBatchLoading){ |
| 2797 |
| --- src/fossil.page.chat.js | |
| +++ src/fossil.page.chat.js | |
| @@ -2732,42 +2732,38 @@ | |
| 2732 | if(true===f.isFirstCall){ |
| 2733 | f.isFirstCall = false; |
| 2734 | Chat.pendingOnError = undefined; |
| 2735 | Chat.ajaxStart(); |
| 2736 | Chat.e.viewMessages.classList.add('loading'); |
| 2737 | /* |
| 2738 | We manager onerror() results in poll() in a roundabout |
| 2739 | manner: when an onerror() arrives, we stash it aside |
| 2740 | for a moment before processing it. |
| 2741 | |
| 2742 | This level of indirection is necessary to be able to |
| 2743 | unambiguously identify client-timeout-specific polling errors |
| 2744 | from other errors. Timeouts are always announced in pairs of |
| 2745 | an HTTP 0 and something we can unambiguously identify as a |
| 2746 | timeout (in that order). When we receive an HTTP error we put |
| 2747 | it into this queue. If an ontimeout() call arrives before |
| 2748 | this error is handled, this error is ignored. If, however, an |
| 2749 | HTTP error is seen without an accompanying timeout, we handle |
| 2750 | it from here. |
| 2751 | |
| 2752 | It's kinda like in the curses C API, where you to match |
| 2753 | ALT-X by first getting an ESC event, then an X event, but |
| 2754 | this one is a lot less explicable. (It's almost certainly a |
| 2755 | mis-handling bug in F.fetch(), but it has so far eluded my |
| 2756 | eyes.) |
| 2757 | */ |
| 2758 | f.delayPendingOnError = function(err){ |
| 2759 | if( Chat.pendingOnError ){ |
| 2760 | const x = Chat.pendingOnError; |
| 2761 | Chat.pendingOnError = undefined; |
| 2762 | afterPollFetch(x); |
| 2763 | } |
| 2764 | }; |
| 2765 | } |
| 2766 | let nErr = 0; |
| 2767 | F.fetch("chat-poll",{ |
| 2768 | timeout: Chat.timer.pollTimeout, |
| 2769 | urlParams:{ |
| @@ -2787,10 +2783,11 @@ | |
| 2783 | Chat._isBatchLoading = false; |
| 2784 | if(Chat.beVerbose){ |
| 2785 | console.error("poll.onerror:",err.name,err.status,JSON.stringify(err)); |
| 2786 | } |
| 2787 | Chat.pendingOnError = err; |
| 2788 | setTimeout(f.delayPendingOnError, 250); |
| 2789 | }, |
| 2790 | onload:function(y){ |
| 2791 | reportConnectionOkay('poll.onload', true); |
| 2792 | newcontent(y); |
| 2793 | if(Chat._isBatchLoading){ |
| 2794 |