@@ -16,6 +16,7 @@ import (
16
16
"text/template"
17
17
"time"
18
18
19
+ "github.com/fsnotify/fsnotify"
19
20
"github.com/jmoiron/sqlx"
20
21
_ "github.com/mattn/go-sqlite3"
21
22
"github.com/urfave/cli/v2"
@@ -249,6 +250,7 @@ func newCmd(db *sqlx.DB) error {
249
250
intervalToShowBreakReminder := cCtx .Duration ("break-interval" )
250
251
intervalToRepeatBreakReminder := cCtx .Duration ("repeat-interval" )
251
252
hook := cCtx .String ("hook" )
253
+
252
254
err := Daemon (db , intervalToUpdateDb , intervalToShowBreakReminder , intervalToRepeatBreakReminder , hook )
253
255
if err != nil {
254
256
return err
@@ -493,6 +495,10 @@ func Daemon(
493
495
) error {
494
496
var notified time.Time
495
497
var lastHook string
498
+ change := make (chan ChangeEvent )
499
+
500
+ go watchDbFile (change )
501
+
496
502
for {
497
503
activity , err := Latest (db )
498
504
if err != nil {
@@ -512,17 +518,12 @@ func Daemon(
512
518
}
513
519
}
514
520
}
515
- if activity .Active () && time .Since (activity .Updated ()) > intervalToUpdateDb {
516
- fmt .Printf ("updating time for %s\n " , activity .Name )
517
- _ , err := UpdateIfExists (db , "" , false )
518
- if err != nil {
519
- return err
520
- }
521
+ if activity .Active () {
521
522
duration , err := activeDuration (db )
522
523
if err != nil {
523
524
return err
524
525
}
525
- if activity . Active () && duration > intervalToShowBreakReminder && time .Since (notified ) > intervalToRepeatBreakReminder {
526
+ if duration > intervalToShowBreakReminder && time .Since (notified ) > intervalToRepeatBreakReminder {
526
527
args := []string {
527
528
"Take a break!" ,
528
529
fmt .Sprintf ("Active for %v already" , formatDuration (duration )),
@@ -540,10 +541,64 @@ func Daemon(
540
541
notified = time .Now ()
541
542
}
542
543
}
543
- time .Sleep (1 * time .Second )
544
+
545
+ nextUpdate := activity .TimeSince ().Truncate (time .Minute ) + time .Minute - activity .TimeSince ()
546
+ log .Printf ("next update in %s\n " , nextUpdate )
547
+
548
+ select {
549
+ case c := <- change :
550
+ log .Println ("change" , c )
551
+
552
+ case <- time .After (nextUpdate ):
553
+ if activity .Active () && time .Since (activity .Updated ()) > intervalToUpdateDb {
554
+ fmt .Printf ("updating time for %s\n " , activity .Name )
555
+ _ , err := UpdateIfExists (db , "" , false )
556
+ if err != nil {
557
+ return err
558
+ }
559
+ }
560
+ }
544
561
}
545
562
}
546
563
564
+ type ChangeEvent struct {
565
+ Event fsnotify.Event
566
+ Error error
567
+ }
568
+
569
+ func watchDbFile (change chan ChangeEvent ) error {
570
+ watcher , err := fsnotify .NewWatcher ()
571
+ if err != nil {
572
+ return err
573
+ }
574
+ defer watcher .Close ()
575
+
576
+ go func () {
577
+ for {
578
+ select {
579
+ case event , ok := <- watcher .Events :
580
+ if ! ok {
581
+ return
582
+ }
583
+ change <- ChangeEvent {Event : event }
584
+
585
+ case err , ok := <- watcher .Errors :
586
+ if ! ok {
587
+ return
588
+ }
589
+ change <- ChangeEvent {Error : err }
590
+ }
591
+ }
592
+ }()
593
+
594
+ if err := watcher .Add (dbFile ); err != nil {
595
+ return err
596
+ }
597
+
598
+ <- make (chan struct {})
599
+ return nil
600
+ }
601
+
547
602
func activeDuration (db * sqlx.DB ) (time.Duration , error ) {
548
603
rows , err := db .Queryx (`SELECT * FROM log ORDER BY started DESC LIMIT 100` )
549
604
if err != nil {
0 commit comments