Skip to content

Commit ae1ed98

Browse files
committed
perf: task directory is created lazily
1 parent a1fb7b4 commit ae1ed98

2 files changed

Lines changed: 19 additions & 6 deletions

File tree

internal/cron/cron.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,15 +338,27 @@ func (s *Store) scheduleDurableWrite() {
338338
// flushDurable serializes under RLock and writes outside the lock.
339339
func (s *Store) flushDurable() {
340340
s.mu.RLock()
341+
jobCount := len(s.durableJobs)
341342
data := s.marshalDurableJobs()
342343
dir := s.configDir
343344
s.mu.RUnlock()
344345

345346
if dir == "" || data == nil {
346347
return
347348
}
349+
filePath := filepath.Join(dir, scheduledTasksFile)
350+
// Skip persisting an empty job list when no file exists yet: StopWriter
351+
// calls this unconditionally on shutdown, and without this guard every
352+
// session that never scheduled a cron task would leave behind an empty
353+
// <sessionID>/scheduled_tasks.json. When the file already exists the
354+
// empty list is still written so that deleting the last job persists.
355+
if jobCount == 0 {
356+
if _, err := os.Stat(filePath); os.IsNotExist(err) {
357+
return
358+
}
359+
}
348360
_ = os.MkdirAll(dir, 0o755)
349-
_ = os.WriteFile(filepath.Join(dir, scheduledTasksFile), data, 0o644)
361+
_ = os.WriteFile(filePath, data, 0o644)
350362
}
351363

352364
// marshalDurableJobs serializes durable jobs to JSON. Must hold at least RLock.

internal/storage/task_store.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -375,12 +375,10 @@ func taskAppendUnique(base []string, vals ...string) []string {
375375

376376
const taskHighWaterMarkFile = ".highwatermark"
377377

378-
// SetDir enables file persistence. It creates the directory if needed and
379-
// loads any existing tasks from disk. Call before the store is used.
378+
// SetDir enables file persistence. The directory is created lazily on the
379+
// first write (persistLocked / writeHighWaterMarkLocked) — sessions that
380+
// never create a task leave nothing behind on disk.
380381
func (s *TaskStore) SetDir(dir string) error {
381-
if err := os.MkdirAll(dir, 0o755); err != nil {
382-
return fmt.Errorf("create task dir: %w", err)
383-
}
384382
s.mu.Lock()
385383
s.dir = dir
386384
s.mu.Unlock()
@@ -390,6 +388,9 @@ func (s *TaskStore) SetDir(dir string) error {
390388
func (s *TaskStore) loadFromDir() error {
391389
entries, err := os.ReadDir(s.dir)
392390
if err != nil {
391+
if os.IsNotExist(err) {
392+
return nil // dir not created yet — no prior tasks to load
393+
}
393394
return fmt.Errorf("read task dir: %w", err)
394395
}
395396

0 commit comments

Comments
 (0)