From e9d4a6b0e8624c6425d467f0efe14be1bc683bd9 Mon Sep 17 00:00:00 2001 From: Ben Morrison Date: Thu, 6 Jun 2019 16:07:53 -0400 Subject: database refs and static assets concurrency-safe --- svc/cache.go | 7 +++++++ svc/db.go | 28 +++++++++++++++++++++++----- svc/handlers.go | 57 ++++++++++++++++++++++++++++++++++----------------------- 3 files changed, 64 insertions(+), 28 deletions(-) diff --git a/svc/cache.go b/svc/cache.go index db427db..6b50a0e 100644 --- a/svc/cache.go +++ b/svc/cache.go @@ -18,6 +18,7 @@ type RemoteRegistries struct { } type staticAssets struct { + mu sync.RWMutex index []byte indexMod time.Time css []byte @@ -98,8 +99,10 @@ func pingAssets() { log.Printf("%v\n", err.Error()) } + staticCache.mu.RLock() indexMod := staticCache.indexMod cssMod := staticCache.cssMod + staticCache.mu.RUnlock() if !indexMod.Equal(indexStat.ModTime()) { tmpls = initTemplates() @@ -114,8 +117,10 @@ func pingAssets() { log.Printf("%v\n", err.Error()) } + staticCache.mu.Lock() staticCache.index = buf.Bytes() staticCache.indexMod = indexStat.ModTime() + staticCache.mu.Unlock() } if !cssMod.Equal(cssStat.ModTime()) { @@ -125,7 +130,9 @@ func pingAssets() { log.Printf("%v\n", err.Error()) } + staticCache.mu.Lock() staticCache.css = css staticCache.cssMod = cssStat.ModTime() + staticCache.mu.Unlock() } } diff --git a/svc/db.go b/svc/db.go index 0bb96ee..e0c2690 100644 --- a/svc/db.go +++ b/svc/db.go @@ -11,6 +11,11 @@ import ( "github.com/syndtr/goleveldb/leveldb" ) +type dbase interface { + push() error + pull() +} + type dbLevel struct { db *leveldb.DB } @@ -19,9 +24,8 @@ type dbSqlite struct { db *sql.DB } -type dbase interface { - push() error - pull() +type dbPostgres struct { + db *sql.DB } // Pull DB data into cache, if available. @@ -41,6 +45,10 @@ func initDatabase() { var lite *sql.DB db = &dbSqlite{db: lite} + case "postgres": + var pg *sql.DB + db = &dbPostgres{db: pg} + } confObj.Mu.RUnlock() @@ -65,15 +73,16 @@ func dbTimer() bool { // database for safe keeping. func pushDB() error { db := <-dbChan + err := db.push() dbChan <- db - return db.push() + return err } func pullDB() { db := <-dbChan - dbChan <- db db.pull() + dbChan <- db } func (lvl dbLevel) push() error { @@ -176,3 +185,12 @@ func (lite dbSqlite) push() error { func (lite dbSqlite) pull() { } + +func (pg dbPostgres) push() error { + + return nil +} + +func (pg dbPostgres) pull() { + +} diff --git a/svc/handlers.go b/svc/handlers.go index 7f7c730..3dcb84f 100644 --- a/svc/handlers.go +++ b/svc/handlers.go @@ -3,27 +3,59 @@ package svc // import "github.com/getwtxt/getwtxt/svc" import ( "crypto/sha256" "fmt" + "log" "net/http" "strconv" + "time" "github.com/getwtxt/registry" "github.com/gorilla/mux" ) +func getEtag(modtime time.Time) string { + shabytes, err := modtime.MarshalText() + if err != nil { + log.Printf("%v\n", err.Error()) + } + return fmt.Sprintf("%x", sha256.Sum256(shabytes)) +} + // handles "/" func indexHandler(w http.ResponseWriter, r *http.Request) { pingAssets() - etag := fmt.Sprintf("%x", sha256.Sum256([]byte(staticCache.indexMod.String()))) - // Take the hex-encoded sha256 sum of the index template's mod time // to send as an ETag. If an error occurred when grabbing the file info, // the ETag will be empty. + staticCache.mu.RLock() + etag := getEtag(staticCache.indexMod) w.Header().Set("ETag", "\""+etag+"\"") w.Header().Set("Content-Type", htmlutf8) _, err := w.Write(staticCache.index) + staticCache.mu.RUnlock() + if err != nil { + log500(w, r, err) + return + } + + log200(r) +} + +// Serving the stylesheet virtually because +// files aren't served directly in getwtxt. +func cssHandler(w http.ResponseWriter, r *http.Request) { + + pingAssets() + + staticCache.mu.RLock() + etag := getEtag(staticCache.cssMod) + w.Header().Set("ETag", "\""+etag+"\"") + w.Header().Set("Content-Type", cssutf8) + + _, err := w.Write(staticCache.css) + staticCache.mu.RUnlock() if err != nil { log500(w, r, err) return @@ -183,24 +215,3 @@ func apiTagsHandler(w http.ResponseWriter, r *http.Request) { log200(r) } - -// Serving the stylesheet virtually because -// files aren't served directly in getwtxt. -func cssHandler(w http.ResponseWriter, r *http.Request) { - - // Sending the sha256 sum of the modtime in hexadecimal for the ETag header - etag := fmt.Sprintf("%x", sha256.Sum256([]byte(staticCache.cssMod.String()))) - - w.Header().Set("ETag", "\""+etag+"\"") - w.Header().Set("Content-Type", cssutf8) - - pingAssets() - - n, err := w.Write(staticCache.css) - if err != nil || n == 0 { - log500(w, r, err) - return - } - - log200(r) -} -- cgit 1.4.1-2-gfad0