summary refs log tree commit diff stats
path: root/svc/cache.go
diff options
context:
space:
mode:
authorBen Morrison <ben@gbmor.dev>2019-06-05 15:36:23 -0400
committerBen Morrison <ben@gbmor.dev>2019-06-05 15:36:23 -0400
commitfd43c61bd128ad77b22db0537a9a4eb58490b0b5 (patch)
tree4c5fa7b33fadbf7c3e14e69b7d68ce280bc3810a /svc/cache.go
parent4658fe82be3e9d95e93fa5c7c7ca64a15cf2f1a1 (diff)
downloadgetwtxt-fd43c61bd128ad77b22db0537a9a4eb58490b0b5.tar.gz
moved bulk of code to its own package to clean up source tree
Diffstat (limited to 'svc/cache.go')
-rw-r--r--svc/cache.go130
1 files changed, 130 insertions, 0 deletions
diff --git a/svc/cache.go b/svc/cache.go
new file mode 100644
index 0000000..ce3813c
--- /dev/null
+++ b/svc/cache.go
@@ -0,0 +1,130 @@
+package svc // import "github.com/getwtxt/getwtxt/svc"
+
+import (
+	"bytes"
+	"io/ioutil"
+	"log"
+	"os"
+	"time"
+)
+
+func checkCacheTime() bool {
+	confObj.Mu.RLock()
+	answer := time.Since(confObj.LastCache) > confObj.CacheInterval
+	confObj.Mu.RUnlock()
+
+	return answer
+}
+
+// Launched by init as a coroutine to watch
+// for the update intervals to pass.
+func cacheAndPush() {
+	for {
+		if checkCacheTime() {
+			refreshCache()
+		}
+		if checkDBtime() {
+			if err := pushDatabase(); err != nil {
+				log.Printf("Error pushing cache to database: %v\n", err.Error())
+			}
+		}
+		time.Sleep(1000 * time.Millisecond)
+	}
+}
+
+func refreshCache() {
+
+	// This clusterfuck of mutex read locks is
+	// necessary to avoid deadlock. This mess
+	// also avoids a panic that would occur
+	// should twtxtCache be written to during
+	// this loop.
+	twtxtCache.Mu.RLock()
+	for k := range twtxtCache.Users {
+		twtxtCache.Mu.RUnlock()
+		err := twtxtCache.UpdateUser(k)
+		if err != nil {
+			log.Printf("%v\n", err.Error())
+		}
+		twtxtCache.Mu.RLock()
+	}
+	twtxtCache.Mu.RUnlock()
+
+	remoteRegistries.Mu.RLock()
+	for _, v := range remoteRegistries.List {
+		err := twtxtCache.CrawlRemoteRegistry(v)
+		if err != nil {
+			log.Printf("Error while refreshing local copy of remote registry user data: %v\n", err.Error())
+		}
+	}
+	remoteRegistries.Mu.RUnlock()
+	confObj.Mu.Lock()
+	confObj.LastCache = time.Now()
+	confObj.Mu.Unlock()
+}
+
+// pingAssets checks if the local static assets
+// need to be re-cached. If they do, they are
+// pulled back into memory from disk.
+func pingAssets() {
+
+	confObj.Mu.RLock()
+	assetsDir := confObj.AssetsDir
+	confObj.Mu.RUnlock()
+
+	cssStat, err := os.Stat(assetsDir + "/style.css")
+	if err != nil {
+		log.Printf("%v\n", err.Error())
+	}
+
+	indexStat, err := os.Stat(assetsDir + "/tmpl/index.html")
+	if err != nil {
+		log.Printf("%v\n", err.Error())
+	}
+
+	indexMod := staticCache.indexMod
+	cssMod := staticCache.cssMod
+
+	if !indexMod.Equal(indexStat.ModTime()) {
+		tmpls = initTemplates()
+
+		var b []byte
+		buf := bytes.NewBuffer(b)
+
+		confObj.Mu.RLock()
+		err = tmpls.ExecuteTemplate(buf, "index.html", confObj.Instance)
+		confObj.Mu.RUnlock()
+		if err != nil {
+			log.Printf("%v\n", err.Error())
+		}
+
+		staticCache.index = buf.Bytes()
+		staticCache.indexMod = indexStat.ModTime()
+	}
+
+	if !cssMod.Equal(cssStat.ModTime()) {
+
+		css, err := ioutil.ReadFile(assetsDir + "/style.css")
+		if err != nil {
+			log.Printf("%v\n", err.Error())
+		}
+
+		staticCache.css = css
+		staticCache.cssMod = cssStat.ModTime()
+	}
+}
+
+// Simple function to deduplicate entries in a []string
+func dedupe(list []string) []string {
+	var out []string
+	var seen = map[string]bool{}
+
+	for _, e := range list {
+		if !seen[e] {
+			out = append(out, e)
+			seen[e] = true
+		}
+	}
+
+	return out
+}