This commit is contained in:
Bendt
2025-12-18 10:07:01 -05:00
parent 523cf78737
commit a934de6bba
2 changed files with 104 additions and 22 deletions

View File

@@ -529,13 +529,17 @@ class SyncDashboard(App):
def action_daemonize(self) -> None:
"""Start sync daemon in background and exit TUI."""
import subprocess
from src.cli.sync_daemon import SyncDaemon, create_daemon_config
# Build config from sync_config, adding sync_interval
daemon_config = {
**self._sync_config,
"sync_interval": self.sync_interval,
}
# Check if daemon is already running
config = create_daemon_config(
sync_interval=self.sync_interval,
notify=True, # Enable notifications for daemon
)
config = create_daemon_config(**daemon_config)
daemon = SyncDaemon(config)
if daemon.is_running():
@@ -548,26 +552,51 @@ class SyncDashboard(App):
# Start daemon and exit
self._log_to_task(self.selected_task, "Starting background daemon...")
# Fork the daemon process
# Use subprocess to start the daemon via CLI command
# This properly handles daemonization without conflicting with TUI
try:
pid = os.fork()
if pid == 0:
# Child process - become the daemon
os.setsid()
# Second fork to prevent zombie processes
pid2 = os.fork()
if pid2 == 0:
# Grandchild - this becomes the daemon
daemon.start()
else:
os._exit(0)
else:
# Parent process - wait briefly then exit TUI
import time
# Build the command with current config
cmd = [
sys.executable,
"-m",
"src.cli",
"sync",
"run",
"--daemon",
"--org",
self._sync_config.get("org", "corteva"),
"--vdir",
self._sync_config.get("vdir", "~/Calendar"),
]
if self._sync_config.get("notify", True):
cmd.append("--notify")
if self._sync_config.get("dry_run", False):
cmd.append("--dry-run")
if self._sync_config.get("two_way_calendar", False):
cmd.append("--two-way-calendar")
if self._sync_config.get("download_attachments", False):
cmd.append("--download-attachments")
time.sleep(0.5)
self.exit(message="Daemon started. Sync continues in background.")
except OSError as e:
# Start the daemon process detached
subprocess.Popen(
cmd,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
stdin=subprocess.DEVNULL,
start_new_session=True,
)
# Give it a moment to start
time.sleep(0.5)
# Verify it started
if daemon.is_running():
self.exit(
message=f"Daemon started (PID {daemon.get_pid()}). Sync continues in background."
)
else:
self._log_to_task(self.selected_task, "Failed to start daemon")
except Exception as e:
self._log_to_task(self.selected_task, f"Failed to daemonize: {e}")
def set_sync_callback(self, callback: Callable) -> None: