about summary refs log tree commit diff stats
path: root/cache.go
diff options
context:
space:
mode:
authorBen Morrison <ben@gbmor.dev>2020-05-09 01:26:15 -0400
committerBen Morrison <ben@gbmor.dev>2020-05-09 01:26:15 -0400
commit460684d77834d65fa47f3534056baa72dfba17ec (patch)
tree15dc1197adcc540c52efb21b5f6d6dc767466cbf /cache.go
parent01b6a93f2cfc8b6dd54045c726d87dedcbf9ccc7 (diff)
downloadapi-460684d77834d65fa47f3534056baa72dfba17ec.tar.gz
consolidating functionality to a single handler
also, making cache interaction more generic.
Diffstat (limited to 'cache.go')
-rw-r--r--cache.go80
1 files changed, 66 insertions, 14 deletions
diff --git a/cache.go b/cache.go
index b15bb50..24744f6 100644
--- a/cache.go
+++ b/cache.go
@@ -1,6 +1,7 @@
 package main
 
 import (
+	"fmt"
 	"io/ioutil"
 	"log"
 	"strings"
@@ -8,6 +9,8 @@ import (
 	"time"
 )
 
+const cacheDuration = 1 * time.Minute
+
 // Holds the cached responses
 type page struct {
 	raw     []byte
@@ -25,6 +28,31 @@ var cache = &cacheWrapper{
 	pages: make(map[string]*page),
 }
 
+// Checks if a page exists in the cache already.
+// If it doesn't, creates an empty entry.
+func unNullPage(path string) {
+	cache.RLock()
+	pageBlob := cache.pages[path]
+	cache.RUnlock()
+
+	if pageBlob == nil {
+		cache.Lock()
+		cache.pages[path] = &page{
+			raw:     []byte{},
+			expires: time.Time{},
+		}
+		cache.Unlock()
+	}
+}
+
+// Returns true if the cached page is good.
+// False if it's stale.
+func (cache *cacheWrapper) isFresh(path string) bool {
+	cache.RLock()
+	defer cache.RUnlock()
+	return time.Now().Before(cache.pages[path].expires)
+}
+
 // Wraps the two cache-checking functions.
 // One for /, the other for various requests.
 func (cache *cacheWrapper) bap(requestPath string) {
@@ -48,24 +76,29 @@ func (cache *cacheWrapper) bap(requestPath string) {
 	}
 }
 
+// yoinks the raw data to send to the requester
+func (cache *cacheWrapper) yoink(path string) []byte {
+	cache.RLock()
+	defer cache.RUnlock()
+
+	return cache.pages[path].raw
+}
+
+// yoinks the expiration for the cache
+func (cache *cacheWrapper) expiresWhen(path string) string {
+	cache.RLock()
+	defer cache.RUnlock()
+
+	return cache.pages[path].expires.Format(time.RFC1123)
+}
+
 // Checks if cache either has expired or has nil copy of
 // the index. If so, it yoinks the page from disk and
 // sets the expiration time.
 func bapIndex() {
-	if cache.pages["/"] == nil {
-		cache.Lock()
-		cache.pages["/"] = &page{
-			raw:     []byte{},
-			expires: time.Time{},
-		}
-		cache.Unlock()
-	}
+	unNullPage("/")
 
-	cache.RLock()
-	expires := cache.pages["/"].expires
-	cache.RUnlock()
-
-	if time.Now().Before(expires) {
+	if cache.isFresh("/") {
 		return
 	}
 
@@ -80,12 +113,31 @@ func bapIndex() {
 
 	cache.pages["/"] = &page{
 		raw:     bytes,
-		expires: time.Now().Add(1 * time.Minute),
+		expires: time.Now().Add(cacheDuration),
 	}
 }
 
 func bapOSVersion(format string) {
+	path := fmt.Sprintf("/%s/osversion", format)
+	unNullPage(path)
 
+	if cache.isFresh(path) {
+		return
+	}
+
+	bytes, err := osVersionQuery(format)
+	if err != nil {
+		log.Printf("Could not query OS version: %s", err.Error())
+		bytes = []byte("Internal Error")
+	}
+
+	cache.Lock()
+	defer cache.Unlock()
+
+	cache.pages[path] = &page{
+		raw:     bytes,
+		expires: time.Now().Add(cacheDuration),
+	}
 }
 
 func bapPkgs(format string)      {}