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.

stephan 2025-04-11 19:35 trunk
Commit 1bfb06c7524b132a4458d014cc1dace02198873483f960e9b79f9f30ecbefe33
1 file changed +29 -32
--- src/fossil.page.chat.js
+++ src/fossil.page.chat.js
@@ -2732,42 +2732,38 @@
27322732
if(true===f.isFirstCall){
27332733
f.isFirstCall = false;
27342734
Chat.pendingOnError = undefined;
27352735
Chat.ajaxStart();
27362736
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
+ };
27692765
}
27702766
let nErr = 0;
27712767
F.fetch("chat-poll",{
27722768
timeout: Chat.timer.pollTimeout,
27732769
urlParams:{
@@ -2787,10 +2783,11 @@
27872783
Chat._isBatchLoading = false;
27882784
if(Chat.beVerbose){
27892785
console.error("poll.onerror:",err.name,err.status,JSON.stringify(err));
27902786
}
27912787
Chat.pendingOnError = err;
2788
+ setTimeout(f.delayPendingOnError, 250);
27922789
},
27932790
onload:function(y){
27942791
reportConnectionOkay('poll.onload', true);
27952792
newcontent(y);
27962793
if(Chat._isBatchLoading){
27972794
--- 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

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button