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