summary refs log tree commit diff stats
path: root/svc/periodic.go
diff options
context:
space:
mode:
Diffstat (limited to 'svc/periodic.go')
-rw-r--r--svc/periodic.go103
1 files changed, 103 insertions, 0 deletions
diff --git a/svc/periodic.go b/svc/periodic.go
new file mode 100644
index 0000000..f27b08e
--- /dev/null
+++ b/svc/periodic.go
@@ -0,0 +1,103 @@
+package svc // import "github.com/getwtxt/getwtxt/svc"
+
+import (
+	"log"
+	"time"
+
+	"github.com/fsnotify/fsnotify"
+)
+
+// Functions and types in this file pertain
+// to periodic, regular actions.
+
+// This is a wrapper for a *time.Ticker
+// that adds another channel. It's used
+// to signal to the ticker goroutines
+// that they should stop the tickers
+// and exit.
+type tick struct {
+	isDB bool
+	t    *time.Ticker
+	exit chan bool
+}
+
+// Creates a new instance of a tick
+func initTicker(db bool, interval time.Duration) *tick {
+	return &tick{
+		isDB: db,
+		t:    time.NewTicker(interval),
+		exit: make(chan bool, 1),
+	}
+}
+
+// Sends the signal to stop the tickers
+// and for their respective goroutines
+// to exit.
+func killTickers() {
+	ct := <-cTickC
+	dt := <-dbTickC
+	ct.exit <- true
+	dt.exit <- true
+}
+
+// Waits for a signal from the database
+// *tick. Either stops the ticker and
+// kills the goroutine or it will
+// update cache / push the DB to disk
+func dataTimer(tkr *tick) {
+	for {
+		select {
+		case signal := <-tkr.t.C:
+			if tkr.isDB {
+				errLog("", pushDB())
+				log.Printf("Database push took: %v\n", time.Since(signal))
+				continue
+			}
+			cacheUpdate()
+			log.Printf("Cache update took: %v\n", time.Since(signal))
+		case <-tkr.exit:
+			tkr.t.Stop()
+			return
+		}
+	}
+}
+
+// Called when a change is detected in the
+// configuration file. Closes log file,
+// closes database connection, stops all
+// tickers, then binds new configuration
+// values, opens new log file, connects to
+// new database, and starts new cache and
+// database tickers.
+func reInit(e fsnotify.Event) {
+	log.Printf("%v. Reloading...\n", e.String())
+
+	if !confObj.StdoutLogging {
+		closeLog <- true
+	}
+
+	killTickers()
+	killDB()
+
+	bindConfig()
+
+	initLogging()
+	initDatabase()
+	initPersistence()
+}
+
+// Starts the tickers that periodically:
+//  - pull new user statuses into cache
+//  - push cached data to disk
+func initPersistence() {
+	confObj.Mu.RLock()
+	cacheTkr := initTicker(false, confObj.CacheInterval)
+	dbTkr := initTicker(true, confObj.DBInterval)
+	confObj.Mu.RUnlock()
+
+	go dataTimer(cacheTkr)
+	go dataTimer(dbTkr)
+
+	dbTickC <- dbTkr
+	cTickC <- cacheTkr
+}