summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--svc/sqlite.go13
1 files changed, 8 insertions, 5 deletions
diff --git a/svc/sqlite.go b/svc/sqlite.go
index fe9622c..40a7ff2 100644
--- a/svc/sqlite.go
+++ b/svc/sqlite.go
@@ -42,10 +42,13 @@ func initSqlite() *dbSqlite {
 	}
 }
 
-func (lite dbSqlite) push() error {
-	err := lite.db.Ping()
-	if err != nil {
-		return err
+func (lite *dbSqlite) push() error {
+	confObj.Mu.Lock()
+	confObj.LastPush = time.Now()
+	confObj.Mu.Unlock()
+
+	if err := lite.db.Ping(); err != nil {
+		lite = initSqlite()
 	}
 
 	tx, err := lite.db.Begin()
@@ -90,7 +93,7 @@ func (lite dbSqlite) push() error {
 	return nil
 }
 
-func (lite dbSqlite) pull() {
+func (lite *dbSqlite) pull() {
 	errLog("Error pinging sqlite DB: ", lite.db.Ping())
 
 	rows, err := lite.pullStmt.Query()
>105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
package svc // import "github.com/getwtxt/getwtxt/svc"

import (
	"bytes"
	"io/ioutil"
	"os"
	"sync"
	"time"
)

// RemoteRegistries holds a list of remote registries to
// periodically scrape for new users. The remote registries
// must have been added via POST like a user.
type RemoteRegistries struct {
	Mu   sync.RWMutex
	List []string
}

type staticAssets struct {
	mu       sync.RWMutex
	index    []byte
	indexMod time.Time
	css      []byte
	cssMod   time.Time
}

func cacheTimer() 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 cacheTimer() {
			refreshCache()
		}
		if dbTimer() {
			err := pushDB()
			errLog("Error pushing cache to database: ", err)
		}
		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)
		errLog("", err)
		twtxtCache.Mu.RLock()
	}
	twtxtCache.Mu.RUnlock()

	remoteRegistries.Mu.RLock()
	for _, v := range remoteRegistries.List {
		err := twtxtCache.CrawlRemoteRegistry(v)
		errLog("Error refreshing local copy of remote registry data: ", err)
	}
	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")
	errLog("", err)

	indexStat, err := os.Stat(assetsDir + "/tmpl/index.html")
	errLog("", err)

	staticCache.mu.RLock()
	indexMod := staticCache.indexMod
	cssMod := staticCache.cssMod
	staticCache.mu.RUnlock()

	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()
		errLog("", err)

		staticCache.mu.Lock()
		staticCache.index = buf.Bytes()
		staticCache.indexMod = indexStat.ModTime()
		staticCache.mu.Unlock()
	}

	if !cssMod.Equal(cssStat.ModTime()) {

		css, err := ioutil.ReadFile(assetsDir + "/style.css")
		errLog("", err)

		staticCache.mu.Lock()
		staticCache.css = css
		staticCache.cssMod = cssStat.ModTime()
		staticCache.mu.Unlock()
	}
}