summary refs log tree commit diff stats
path: root/cache.go
diff options
context:
space:
mode:
Diffstat (limited to 'cache.go')
-rw-r--r--cache.go90
1 files changed, 62 insertions, 28 deletions
diff --git a/cache.go b/cache.go
index 253de98..be3d7d3 100644
--- a/cache.go
+++ b/cache.go
@@ -10,18 +10,20 @@ import (
 	"github.com/syndtr/goleveldb/leveldb"
 )
 
-// checks if it's time to refresh the cache or not
+// Checks whether it's time to refresh
+// the cache.
 func checkCacheTime() bool {
 	return time.Since(confObj.lastCache) > confObj.cacheInterval
 }
 
-// checks if it's time to push the cache to the database
+// Checks whether it's time to push
+// the cache to the database
 func checkDBtime() bool {
 	return time.Since(confObj.lastPush) > confObj.dbInterval
 }
 
-// launched by init as a goroutine to constantly watch
-// for the update interval to pass
+// Launched by init as a goroutine to constantly watch
+// for the update interval to pass.
 func cacheAndPush() {
 	for {
 		if checkCacheTime() {
@@ -35,9 +37,11 @@ func cacheAndPush() {
 	}
 }
 
-// refreshes the cache
+// Refreshes the cache.
 func refreshCache() {
 
+	// Iterate over the registry and
+	// update each individual user.
 	for k := range twtxtCache.Reg {
 		err := twtxtCache.UpdateUser(k)
 		if err != nil {
@@ -46,6 +50,9 @@ func refreshCache() {
 		}
 	}
 
+	// Re-scrape all the remote registries
+	// to see if they have any new users
+	// to add locally.
 	for _, v := range remoteRegistries.List {
 		err := twtxtCache.ScrapeRemoteRegistry(v)
 		if err != nil {
@@ -57,40 +64,46 @@ func refreshCache() {
 	confObj.mu.Unlock()
 }
 
-// pushes the registry's cache data to a local
-// database for safe keeping
+// Pushes the registry's cache data to a local
+// database for safe keeping.
 func pushDatabase() error {
+	// Acquire the database from the aether.
+	// goleveldb is concurrency-safe, so we
+	// can immediately push it back into the
+	// channel for other functions to use.
 	db := <-dbChan
-	twtxtCache.Mu.RLock()
+	dbChan <- db
 
-	// create a batch write job so it can
+	// Create a batch write job so it can
 	// be done at one time rather than
-	// per value
+	// per entry.
+	twtxtCache.Mu.RLock()
 	var dbBasket *leveldb.Batch
 	for k, v := range twtxtCache.Reg {
-		dbBasket.Put([]byte(k+".Nick"), []byte(v.Nick))
-		dbBasket.Put([]byte(k+".URL"), []byte(v.URL))
-		dbBasket.Put([]byte(k+".IP"), []byte(v.IP))
-		dbBasket.Put([]byte(k+".Date"), []byte(v.Date))
+		dbBasket.Put([]byte(k+"*Nick"), []byte(v.Nick))
+		dbBasket.Put([]byte(k+"*URL"), []byte(v.URL))
+		dbBasket.Put([]byte(k+"*IP"), []byte(v.IP))
+		dbBasket.Put([]byte(k+"*Date"), []byte(v.Date))
 		for i, e := range v.Status {
-			dbBasket.Put([]byte(k+".Status."+i.String()), []byte(e))
+			rfc := i.Format(time.RFC3339)
+			dbBasket.Put([]byte(k+"*Status*"+rfc), []byte(e))
 		}
 	}
+	twtxtCache.Mu.RUnlock()
 
-	// save our list of remote registries to scrape
+	// Save our list of remote registries to scrape.
 	for k, v := range remoteRegistries.List {
-		dbBasket.Put([]byte("remote."+string(k)), []byte(v))
+		dbBasket.Put([]byte("remote*"+string(k)), []byte(v))
 	}
 
-	// execute the batch job
+	// Execute the batch job.
 	if err := db.Write(dbBasket, nil); err != nil {
 		return err
 	}
 
-	twtxtCache.Mu.RUnlock()
-	dbChan <- db
-
-	// update the last push time
+	// Update the last push time for
+	// our timer/watch function to
+	// reference.
 	confObj.mu.Lock()
 	confObj.lastPush = time.Now()
 	confObj.mu.Unlock()
@@ -98,29 +111,42 @@ func pushDatabase() error {
 	return nil
 }
 
-// pulls registry data from the DB on startup
+// Pulls registry data from the DB on startup.
+// Iterates over the database one entry at a time.
 func pullDatabase() {
+	// Acquire the database from the aether.
+	// goleveldb is concurrency-safe, so we
+	// can immediately push it back into the
+	// channel for other functions to use.
 	db := <-dbChan
+	dbChan <- db
 
 	iter := db.NewIterator(nil, nil)
 
+	// Read the database key-by-key
 	for iter.Next() {
 		key := iter.Key()
 		val := iter.Value()
 
-		split := strings.Split(string(key), ".")
+		split := strings.Split(string(key), "*")
 		urls := string(split[0])
 		field := string(split[1])
-		data := registry.NewUserData()
 
+		// Start with an empty Data struct. If
+		// there's already one in the cache, pull
+		// it and use it instead.
+		data := registry.NewUserData()
 		twtxtCache.Mu.RLock()
 		if _, ok := twtxtCache.Reg[urls]; ok {
 			data = twtxtCache.Reg[urls]
 		}
 		twtxtCache.Mu.RUnlock()
-
 		ref := reflect.ValueOf(data).Elem()
 
+		// Use reflection to find the right field
+		// in the Data struct. Once found, assign
+		// the value and break so the DB iteration
+		// can continue.
 		if field != "Status" && urls != "remote" {
 			for i := 0; i < ref.NumField(); i++ {
 
@@ -132,6 +158,9 @@ func pullDatabase() {
 			}
 		} else if field == "Status" && urls != "remote" {
 
+			// If we're looking at a Status entry in the DB,
+			// parse the time then add it to the TimeMap under
+			// data.Status
 			thetime, err := time.Parse("RFC3339", split[2])
 			if err != nil {
 				log.Printf("%v\n", err)
@@ -139,11 +168,18 @@ func pullDatabase() {
 			data.Status[thetime] = string(val)
 
 		} else {
+			// The third and final possibility is
+			// if we've come across an entry for
+			// a remote twtxt registry to scrape.
+			// If so, add it to our list.
 			remoteRegistries.Mu.Lock()
 			remoteRegistries.List = append(remoteRegistries.List, string(val))
 			remoteRegistries.Mu.Unlock()
+			continue
 		}
 
+		// Push the data struct (back) into
+		// the cache.
 		twtxtCache.Mu.Lock()
 		twtxtCache.Reg[urls] = data
 		twtxtCache.Mu.Unlock()
@@ -154,6 +190,4 @@ func pullDatabase() {
 	if err != nil {
 		log.Printf("Error while pulling DB into registry cache: %v\n", err)
 	}
-
-	dbChan <- db
 }