"fossil ui" idle timeout
(1) By Richard Hipp (drh) on 2020-04-09 12:23:34 [link] [source]
If you are point-and-click oriented (I am not, but many people are these days), it seems like if you double-click on a Fossil repository file that it should bring up a GUI for the repository using the "fossil ui FileThatYouClickedOn" command. This is particularly useful for the Fossil repository as document idea → You double-click on the document, and it pops up in your web-browser.
The problem is that "fossil ui" would be left running forever in the background. So even after you close the web-browser page that initially pops up, the "fossil ui" command is still setting there, idle, taking up a TCP/IP slot and waiting on new HTTP requests to come in.
Proposed Fix:
Modify the "fossil ui" command so that it times out and exits if it does not receive any new HTTP requests for an interval of (say) 60 seconds. This idle timeout can be adjusted or turned off using command-line options.
Web pages generated by "fossil ui" (but not by other HTTP mechanisms) and delivered to the loopback IP address are augmented with a small javascript routine that "phones home" to the "fossil ui" command every 20 seconds or so using XMLHttpRequest(). The XMLHttpRequest() would target a new "/keep-alive" page that replies with just the text "ack".
Questions:
Would this work? Could we count on a javascript routine running every 20 seconds or so in order to keep the "fossil ui" command alive? What if the page in question is on a hidden tab? What if the whole web-browser is iconified - do the JS timer events keep running?
What happens if the computer goes to sleep? Would that confuse the idle timeout and cause the "fossil ui" command to terminate immediately upon wake-up, before the JS had a chance to send in one of its periodic /keep-alive requests?
If something goes wrong and one or more /keep-alive requests fail, should the JS disable all hyperlinks on the page so that if the user clicks on the hyperlink they are not disappointed with a 404 reply? Perhaps after one or more failed /keep-alives, the JS should reconfigure all hyperlinks to pop-up a dialog box saying that the "fossil ui" command has died?
(2) By anonymous on 2020-04-09 13:14:44 in reply to 1 [link] [source]
if you double-click on a Fossil repository file that it should bring up a GUI for the repository using the "fossil ui FileThatYouClickedOn" command
Some people might prefer Fossil to only pass the command line option required to turn on the keep-alive mode in the double-click handler but keep the behaviour off by default in fossil ui
. The final decision is up to you, of course.
What if the page in question is on a hidden tab? What if the whole web-browser is iconified - do the JS timer events keep running?
AFAIK, the API to do that would be setInterval, and it does work with the tab or the whole browser in the background.
What happens if the computer goes to sleep?
My understanding is that the Fossil process, not the browser process should be concerned about that. On the server-side, it's the difference between CLOCK_MONOTONIC
and CLOCK_REALTIME
(but might be harder on Windows).
If something goes wrong and one or more /keep-alive requests fail, should the JS disable all hyperlinks on the page
A bright-colored warning somewhere on the page may be enough, IMO.
so that if the user clicks on the hyperlink they are not disappointed with a 404 reply?
Probably not 404, but "connection refused" browser error page.
(3.1) By Stephan Beal (stephan) on 2020-04-09 13:56:00 edited from 3.0 in reply to 1 [link] [source]
To expand a bit on what our anonymous poster already said...
Hidden/sleeping tabs: my experience is that on desktop systems JS keeps running but on mobile not (which is irrelevant, as mobile is not a concern for your proposed feature).
System sleep mode: typically kills network sockets when the non-sleeping remote times out. Whether that applies to sockets on the same system, i am not sure. Conceivably both sides of a localhost server/client socket can recover from sleep. i use sleep mode multiple times per day on this system and have yet to experience any problems with local server-based services like Apache or
fossil ui
, but have never tested recovery of an open/keepalive'd/websocket localhost connection after sleep mode. How JS'ssetInterval()
responds to waking up from a long sleep is a complete mystery to me, but StackOverflow has something to say about it, including W3 citations, and one response has a simple test page/script to try out how the browser responds.Breaking hyperlinks when the backend dies: i tend to agree with the anonymous respondent that a "highly visible" notification is more conventional. (That said, modifying all links when the connection dies is certainly possible and might make more sense in this context.) Several mobile apps i use pop up a so-called "toast" message (and only now, in the context of "pop up", does the name "toast" finally make sense to me) alerting the user if the app goes offline. In the case of a dead keepalive, there's probably(?) no(?) recovery if the server is restarted, but non-keepalive XHR requests could recover in that case once the remote is restored.
i'm not entirely convinced that this feature would be all that useful, but am an unrepentant CLI user, so am admittedly not the target audience.
(4) By Richard Hipp (drh) on 2020-04-09 14:47:13 in reply to 3.1 [source]
i'm not entirely convinced that this feature would be all that useful, but am an unrepentant CLI user
I'm guessing that it would allow me to end my "fossil ui
" commands with "&
"
and thus free up my shell for other commands even while the UI is running.
(5) By Richard Hipp (drh) on 2020-04-09 17:27:19 in reply to 1 [link] [source]
An implementation of this idea can now be seen on the idle-timeout branch.
It seems to be working, on linux, mac, and windows. If you start up
"fossil ui
" and then close the resulting browser window, the "fossil ui
"
command shuts itself down after about 60 seconds.
Please try it out. Review the implementation. In the absence of objections, I will merge it to trunk in a day or two.
(6.1) By sean (jungleboogie) on 2020-04-09 19:31:42 edited from 6.0 in reply to 5 [link] [source]
Hello,
While using Windows 10, Fossil shuts down the server after a minute of inactivity.
Using this version:
> .\fossil.exe version
This is fossil version 2.11 [eb750c284a] 2020-04-09 17:29:48 UTC
Here I'm starting UI, letting Firefox open the window and never clicking anything in in:
> .\fossil.exe ui .\sqlite-docs-20200407.wdf
Temporary files: C:\Users\user\AppData\Local\Temp\fossil_server_P8080*
Listening for HTTP requests on TCP port 8080
Launch webbrowser: start http://localhost:8080/ &
Type Ctrl-C to stop the HTTP server
The firefox window/tab is never closed nor are any links clicked.
Additionally, even if I click a link or two after Fossil launches the new tab, the process will die out after a minute of inactivity with the tab still open.
(7) By Richard Hipp (drh) on 2020-04-09 19:42:52 in reply to 6.1 [link] [source]
Add the "--systemtrace
" option to the "fossil ui
" command. You should see
activity every 15 seconds or so as the web-browser polls the server with
keep-alive requests. If not, that is why the server is giving up.
Do you have javascript disabled in your browser, perhaps?
(8.1) By sean (jungleboogie) on 2020-04-09 20:00:50 edited from 8.0 in reply to 7 [link] [source]
Javascript is enabled in my Firefox 74 browser. I don't see any keepalive messages at all.
edit... Obvious there are keepalive messages below, but those are all printed out immediately after starting fossil ui.
> .\fossil.exe ui --systemtrace .\sqlite-docs-20200407.wdf
Temporary files: C:\Users\user\AppData\Local\Temp\fossil_server_P8080*
Listening for HTTP requests on TCP port 8080
Launch webbrowser: start http://localhost:8080/ &
SYSTEM: "start http://localhost:8080/ &"
Type Ctrl-C to stop the HTTP server
SYSTEM: ""C:\Users\sean\bin\fossil-new\new-test\fossil.exe" http -args "C:\Users\user\AppData\Local\Temp\fossil_server_P8080_000001_cmd.txt" --nossl --localauth --keep-alive --repolist"
SYSTEM: ""C:\Users\sean\bin\fossil-new\new-test\fossil.exe" http -args "C:\Users\user\AppData\Local\Temp\fossil_server_P8080_000002_cmd.txt" --nossl --localauth --keep-alive --repolist"
SYSTEM: ""C:\Users\sean\bin\fossil-new\new-test\fossil.exe" http -args "C:\Users\user\AppData\Local\Temp\fossil_server_P8080_000003_cmd.txt" --nossl --localauth --keep-alive --repolist"
SYSTEM: ""C:\Users\sean\bin\fossil-new\new-test\fossil.exe" http -args "C:\Users\user\AppData\Local\Temp\fossil_server_P8080_000004_cmd.txt" --nossl --localauth --keep-alive --repolist"
(9) By Richard Hipp (drh) on 2020-04-09 20:09:32 in reply to 8.1 [link] [source]
Those not keep-alive messages, I don't think. They are, rather, the HTTP requests for the page content and the CSS and a few images, perhaps.
Please look at the "Page Source". Very near the bottom, do you see a line that says:
setInterval(function(){fetch('/noop');},15000+10000*Math.random());
That is the line that should be sending the keep-alive messages. If the line is there, please go into debug mode in Firefox and try to figure out why that code is not running.
(10) By sean (jungleboogie) on 2020-04-09 20:24:45 in reply to 9 [link] [source]
When launching fossil with
> .\fossil.exe ui --systemtrace .\sqlite-docs-20200407.wdf
Which is the sqlitedoc repo, I do not see that function. I am able to copy/paste that function into Firefox's console and see the responses in the fossil window.
(12) By Richard Hipp (drh) on 2020-04-09 21:03:26 in reply to 10 [link] [source]
I think I understand now...
The keepalive.js file only gets added into the output for pages where Fossil generates the HTML itself. The sqlite-docs-20200407.wdf repository is a bunch of HTML files that are delivered as is and so the keepalive.js code is not being added in.
I will have to think about ways of solving that problem....
(13) By sean (jungleboogie) on 2020-04-09 22:14:24 in reply to 12 [link] [source]
Ah, I see. Yes, creating a new repo, I do see where the javascript has been injected. I also see the frequent keep-alive messages when using --systemtrace.
Thanks for the help and I apologize for not trying a real repo first.
(11) By Andy Bradford (andybradford) on 2020-04-09 20:56:26 in reply to 5 [link] [source]
Does it default to off to preserve historical behavior? Andy
(14) By Richard Hipp (drh) on 2020-04-10 12:46:46 in reply to 1 [link] [source]
Would this work?
Answer: Almost
It works most of the time but falls down for the following scenarios:
If the repository serves any HTML pages as-is (example) then those as-is pages will not have the keep-alive javascript and will thus allow the "
fossil ui
" command to time-out.If the "Back" button is used in the web-browser to go back to a pages that has not been viewed in a while. The "
fossil ui
" command will have timed out by that point.
It might be possible to ignore the second objection (the "Back" button).
The first objection can be worked around by parsing as-is HTML content
and inserting the appropriate <script>
element to run the keep-alive.
A prototype that works for cases other than the two listed above is on the idle-timeout branch. I could implement further changes to work around the first problem. But that is beginning to get kind of hacky. For that reason, I am going to abandon the branch, and this idea, for the time being. Maybe we can revisit it later if anybody comes up with a clever new idea to make it work better.
(15) By Florian Balmer (florian.balmer) on 2020-04-10 14:06:43 in reply to 14 [link] [source]
I am going to abandon the branch ...
My feelings during testing were somewhat mixed. I figured it might probably result in an enhancement to certain workflows if the local web server shutdown itself after an idle timeout.
I've uploaded some suggestions for modifications to the feature to address issues found during testing, anyway. The main issue was that the Javascript polling interval was allowed to be longer than the idle timeout.
Regarding ".wdf" documents: maybe a "PDF-amalgamation" of the SQLite docs, to be viewed and archived offline, would be helpful to the people who triggered reasoning about the ".wdf" feature?
(Sometimes I create "PDF-amalgamations" from large documentation web sites, to bypass the menu and chapter structure and the search interface, and quickly jump between search terms in different contexts using the search features of my PDF program.)
I'm guessing that it would allow me to end my "
fossil ui
" commands with "&
" and thus free up my shell for other commands even while the UI is running.
On Windows, the equivalent for CMD.EXE is:
start "" /b fossil ui
Note that now Ctrl+Break
is required to stop the server, since Ctrl+C
will only work for the foreground process.
(16) By Florian Balmer (florian.balmer) on 2020-04-15 13:03:47 in reply to 15 [link] [source]
Note that now
Ctrl+Break
is required to stop the server, sinceCtrl+C
will only work for the foreground process.
Looks like I've fallen for my own lazy magic trick!
In my tests, I set an idle timeout just long enough for the "ui" server to be still alive after pressing Ctrl+C
, and just short enough for the server to (automatically) terminate right after pressing Ctrl+Break
.
On Windows, in a traditional Console Host window (i.e. not the new Windows Terminal) running the CMD.EXE shell, Ctrl+Break
will NOT be delivered to background processes.
The required action to terminate a background "ui" server is:
taskkill /f /im fossil.exe
This will terminate all Fossil instances, i.e. also persistent servers and (with sufficient privileges) services. The taskkill
utility also has a /pid
option that could useful, if the status display for fossil ui
were modified to include the PID.
(The excellent YORI shell for Windows, usable without installation, supports launching background processes by appending &
to the command-line, and terminating them by job kill <id>
, maybe quite similar to the *nix (:?ba)?sh
shells.)
(17) By anonymous on 2020-04-16 23:11:33 in reply to 16 [link] [source]
(The excellent YORI shell for Windows ... maybe quite similar to the *nix (:?ba)?sh shells.)
Interesting and very similar to *nix shells. But, it has differences that make its similarities confusing.
For example, Yori uses ~desktop to refer to the current user's Desktop folder. In *nix shells, ~desktop refers to the home directory of a user named "desktop".
Still, it seems to have some features to make some things easier on MS Windows.