BINLANDER
SDK MODEL: INTEGRATED UPDATER SERVICE
DEVELOPER
main.go
import
"binlander"
func
main()
{
bl := binlander.
New
(config)
bl.
Start
()
// Your app...
bl.
Stop
()
}
SDK Integration
go build
-ldflags
GOOS=darwin
GOARCH=arm64
Compile
Your App Logic
Binlander SDK
Service Daemon
BINLANDER
Embedded Service
codesign
notarize
Sign
END USER
Your App
↻
launchd / systemd
com.app.updater running
Persistent Service
</>
SDK Integration
Import and initialize
⚙
System Service
launchd, systemd, Windows Service
⌘
Cross-Platform
Mac, Windows, Linux
↻
Background Updates
Persistent daemon
SDK MODEL
BINLANDER
SDK MODEL: COMPLETE ECOSYSTEM WITH MISSION CONTROL
SDK MODEL
v2.4.1 LIVE
MISSION CONTROL
Update Server
DEVELOPER
Your App + SDK
App Logic
Binlander SDK
Service Daemon
kardianos/service
Integrated Binary
go build
GOOS=darwin
codesign
Build + Sign
PUSH
END USERS
Your App v2.4.1
Updater Service Running
System Service
launchd • systemd
Auto-restart on failure
Persistent Daemon
UPDATE
POLL
SDK MODEL FEATURES
</>
SDK Integration
Import, configure, embed
⚙
System Services
launchd, systemd, Windows
↑
Privilege Escalation
UAC, sudo handled
⊞
Registry/plist
Platform-specific config
◉
Health Checks
Disk, network, self-monitor
⤴
Signal Handling
SIGTERM, SIGHUP, graceful
↺
Atomic Updates
Backup, swap, rollback
☁
Mission Control
Hosted or self-host
✓
Signature Verify
RSA, SHA256 checksums
▶
Auto-Restart
Crash recovery built-in
📋
Structured Logs
JSON, slog integration
🔒
TLS Pinning
Secure communication
Full Control
Deep OS integration
Custom update logic
Platform APIs
Visible Service
Tray icon option
User can see status
System preferences
DEVELOPER EXPERIENCE
SDK Model: Integrate the library, manage service lifecycle
SDK MODEL
1
Add SDK
2
Integrate
3
Configure
4
Build
5
Deploy
Terminal
$
go get
github.com/binlander/sdk
go: downloading binlander/sdk v2.4.1
go: downloading kardianos/service v1.2.2
go: downloading golang.org/x/sys
go: added github.com/binlander/sdk v2.4.1
Pulls kardianos/service for cross-platform daemon support
main.go
package
main
import
(
"github.com/binlander/sdk"
)
func
main
() {
svc := binlander.
NewService
(cfg)
svc.
Run
()
// Blocks, runs as daemon
SDK takes over main() - handles signals, lifecycle, updates
config.go
cfg := binlander.
Config
{
UpdateURL:
"https://updates.myapp.com",
CheckInterval:
time.Hour,
ServiceName:
"com.myapp.updater",
InstallPath:
"/usr/local/bin",
OnUpdate:
handleUpdate
,
}
Callbacks for custom update logic
PLATFORM SERVICE INSTALLATION
macOS - LaunchDaemon
/Library/LaunchDaemons/com.myapp.updater.plist
<key>
Label
</key>
<string>
com.myapp.updater
</string>
<key>
KeepAlive
</key>
<true/>
<key>
RunAtLoad
</key>
<true/>
launchctl load /Library/LaunchDaemons/...
Windows - Service Manager
// Uses golang.org/x/sys/windows/svc/mgr
m, _ := mgr.
Connect
()
s, _ := m.
CreateService
(name, exe,
mgr.Config{
StartType:
mgr.StartAutomatic,
})
// Handles UAC elevation automatically
Linux - systemd
/etc/systemd/system/myapp-updater.service
[Unit]
Description=MyApp Updater Service
[Service]
Restart
=always
ExecStart
=/usr/local/bin/myapp --service
systemctl enable myapp-updater
SIGNAL HANDLING AND LIFECYCLE
service.go
func
(s *Service)
handleSignals
() {
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan,
syscall.SIGTERM
,
// Graceful shutdown
syscall.SIGHUP
,
// Reload config
syscall.SIGINT
)
// Interrupt
Signal Response
SIGTERM
→ Stop()
SIGHUP
→ Reload()
SIGINT
→ Stop()
ATOMIC UPDATE WORKFLOW
1. Download
to /tmp
2. Verify
SHA256 + sig
3. Backup
old → .backup
4. Swap
atomic rename
5. Restart
service reload
Rollback?
restore backup
health
check
SDK MODEL: WHAT DEVELOPERS GET
</>
Full Control
Custom update callbacks, platform APIs,
registry access, deep OS integration
⚙
System Service
Persistent daemon, auto-restart on crash,
runs at boot, proper signal handling
↑
Privilege Elevation
UAC, sudo handled automatically,
system-level installs supported
⚠
Tradeoff: Complexity
Requires code changes, platform-specific
testing, service visible to users
THE USER EXPERIENCE
SDK Model: Visible service integration with system-level access
SDK MODEL
WHAT THEY SEE
BEHIND THE SCENES
1
Download
myapp.com/download
Download MyApp
Version 2.4.1 for macOS
Download
"Normal download page"
Downloaded package contains:
MyApp.pkg / MyApp.exe
Your App + Binlander SDK
Embedded Service Daemon
SDK Model Difference
• SDK compiled into binary
• Service code embedded
• Larger binary size
• Developer signed
2
Install
Installer
!
"MyApp" wants to make changes
Enter your password to allow this.
••••••••
"Needs my password..." (UAC/sudo)
Installation process:
1
Request elevation (UAC/sudo)
2
Install to /usr/local/bin or C:\Program Files
3
Register system service (launchd/systemd/SCM)
4
Start service daemon
5
Modify PATH / registry (if needed)
Installed files
/usr/local/bin/myapp
/Library/LaunchDaemons/
com.myapp.updater.plist
/var/log/myapp/
/etc/myapp/config.json
3
Use (Ongoing)
MyApp
Updater service running
Check for updates
"I can see the updater service"
Service daemon activity:
com.myapp.updater
Status:
Running
PID:
48291
Memory:
12.4 MB
Uptime:
3d 14h
Last check:
2m ago
Next check:
58m
Activity log:
14:32
Version check: v2.4.1 is current
13:32
Version check: v2.4.1 is current
12:32
Update available: v2.4.2
12:33
Downloading update...
Visible to User
⚙
System Preferences → Services
◉
Activity Monitor (process)
⬡
Menu bar tray icon (optional)
↻
Update notification popup
SDK MODEL: USER EXPERIENCE TRADEOFFS
✓
Reliable Updates
System service ensures updates
even if app isn't running
↺
Auto-Recovery
Service restarts automatically
if it crashes
⚠
Visible Process
Users can see the service in
Activity Monitor / Task Manager
🔑
Password Prompt
Install requires admin/root
for system service registration
◉
Resource Usage
Always-running daemon uses
small amount of memory