2025.021 20250101 1 0 0 0 1 1.0 © 2026 Tim Parnell Bare bones demo of setting up Watchdog in a Web App 1 400689151 3 0 0 0 384 1 1 1 WatchdogTimer com.strawberrysw.watchdogtimer WatchdogTimer.exe 0 Tim Parnell 0 1 1 WatchdogTimer 80 443 1 8080 1 Launching... The application has gone off-line. Please try again later. WatchdogTimer 1 4 1 0 0 0 0 0 App 0 1 WebApplication 1 0 1 Opening 1 585842687 134217984 Sub Opening(args() As String) #pragma unused args // ==== Initialize your app ==== // Database Connection // Other setup // Long tasks go here first // Watchdog needs to be the very last step of your Web App Opening event // because it sends a message to Linux announcing the app is done launching WatchdogTimer.Initialize // The "Application is ready" message prints to Lifeboat's log (from the Web Framework) End Sub Stopping 1 1409732607 134217984 Sub Stopping(shuttingDown as Boolean) if shuttingDown then WatchdogTimer.Stopping end End Sub 0 Build Automation 0 Linux 1464950783 Build 2129565695 Mac OS X 1464950783 Build 1239724031 Sign 1239724031 Windows 1464950783 Build 967581695 Xojo Cloud 1464950783 Build 1176610815 WatchdogTimer 0 1 Timer 1 0 Action 1 591843327 134217984 Sub Action() #if TargetLinux then // Tell SystemD that we're still here Send(States.Watchdog, "1") #endif End Sub Initialize 1 429029375 134217984 Shared Sub Initialize() #if TargetXojoCloud then #pragma Error "Do not use the WatchdogTimer on Xojo Cloud!" #endif // Already set up if moof <> nil then return end #if TargetLinux then // I'm sorry, I couldn't help myself once the prefix was "m" moof = new WatchdogTimer moof.Enabled = true moof.Period = kWatchdogSec * 1000 moof.RunMode = Timer.RunModes.Multiple moof.Reset // Tell Linux we're ready now Send(States.Ready, "1") #endif End Sub 134217984 0 1 SystemDIsInstalled 1 488957951 134217984 Shared Function SystemDIsInstalled() As Boolean //int sd_watchdog_enabled(int unset_environment, uint64_t *usec); #If TargetLinux Soft Declare Function sd_watchdog_enabled Lib "libsystemd.so" (env As Integer, ByRef usec As UInt64) As Integer If System.IsFunctionAvailable("sd_watchdog_enabled", "libsystemd.so") Then Dim n As UInt64 Dim rv As Integer = sd_watchdog_enabled(0, n) Return rv > 0 End If #EndIf Return False End Function 134217984 33 1 Boolean Send (TargetConsole and (Target32Bit or Target64Bit)) or (TargetWeb and (Target32Bit or Target64Bit)) 1 2031777791 134217984 Shared Sub Send(status as States, statusmessage as string) // int sd_notify(int unset_environment, const char *state); #if TargetLinux and TargetConsole if SystemDIsInstalled then soft declare sub sd_notify lib "libsystemd.so" (env as Integer, state as CString) if System.IsFunctionAvailable("sd_notify", "libsystemd.so") then var msg as String if statusmessage = "" then statusmessage = "1" end select case status case States.Ready // Tell SystemD that we're ready msg = "READY" case States.Stopping // Tell SystemD that we're stopping msg = "STOPPING" case States.Status // Send our current status to SystemD msg = "STATUS" case States.MainPID // If the system asks for our process ID, return it soft declare function getpid lib "libc" () as Integer if System.IsFunctionAvailable("getpid", "libc") then msg = "MAINPID" statusmessage = str(getpid, "0") end case States.Watchdog // Tell SystemD that we're still here msg = "WATCHDOG" // Check to see if watchdog is enabled if System.IsFunctionAvailable("sd_watchdog_enabled", "libsystemd.so") then soft declare function sd_watchdog_enabled lib "libsystemd.so" (env as Integer, byref usec as UInt64) as Integer var usec as UInt64 var sdEnabled as Integer = sd_watchdog_enabled(0, usec) if sdEnabled < 1 then msg = "" statusmessage = "" end else stderr.WriteLine("System level watchdog is not enabled") moof.RunMode = Timer.RunModes.Off end end select if msg <> "" and statusmessage <> "" then sd_notify(0, msg + "=" + statusmessage) end else stderr.WriteLine("sd_notify is unavailable") moof.RunMode = Timer.RunModes.Off end end #else #pragma unused status #pragma unused statusmessage #endif End Sub 134217984 33 1 status as States, statusmessage as string Stopping 1 358088703 134217984 Shared Sub Stopping() // Tell Linux we're done now #if TargetLinux and (not TargetXojoCloud) then Send(States.Stopping, "1") #endif End Sub 134217984 0 1 README 1 810672127 134217984 README # WatchdogTimer This is a self-contained class to send the WATCHDOG=1 message to systemd. While the original plan had been to include the SystemD module from Greg O', it logged the WATCHDOG=1 message every time, which _very quickly_ filled up the Lifeboat logs. The core has been extracted and you can read the original copyright notice in the COPYRIGHT note on this class. The original xojo-console-signals project can be found at: <https://github.com/stretch327/xojo_console_signals> ## Lifeboat Setup Reminder Be sure to set the Lifeboat `WatchdogSec=` setting to _at least double_ the kWatchdogSec value! 0 COPYRIGHT 1 1881167871 134217984 COPYRIGHT # WatchdogTimer <https://strawberrysw.com/lifeboat> Copyright (c) 2026 Tim Parnell Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # xojo_console_signals <https://github.com/stretch327/xojo_console_signals> Copyright (c) 2024 Greg O'Lone Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 0 moof 1 2031937535 134217984 Shared moof As WatchdogTimer 134217984 moof As WatchdogTimer 33 1 kWatchdogSec 1 1094512639 134217984 2 15 33 134217984 33 0 States 1 1132257279 134217984 Ready Stopping Status MainPID Watchdog Unused 0 Session 223383551 1 WebSession 1 0 False False 0 True You have been disconnected from this application. We are having trouble communicating with the server. Please wait a moment while we attempt to reconnect. pgMain 223383551 1 WebPage 1 0 0.00 0 0 0 True True False True False True False False 0 False 0 0 -2147483648 0 0 True Watchdog Example 400 600 400 600 0 1 0 App.Opening 0