3705: describe BlockWorkList flow more explicitly
authorTim Pierce <twp@curoverse.com>
Mon, 15 Sep 2014 22:19:40 +0000 (18:19 -0400)
committerTim Pierce <twp@curoverse.com>
Mon, 15 Sep 2014 22:19:40 +0000 (18:19 -0400)
Updated file comments to describe the overall data flow for a
BlockWorkList manager and worker more explicitly.

services/keepstore/block_work_list.go

index 704a9ca35b8f06800130a7612db5b5f65d6bb75a..a79e4e705124379c131395e4d4e195b5971794fa 100644 (file)
@@ -2,18 +2,43 @@ package main
 
 /* A BlockWorkList concurrently processes blocks needing attention.
 
+   The BlockWorkList object itself manages a list of generic objects,
+   replacing the list when new data is available, and delivering items
+   from the list to consumers when requested.  The overall work flow
+   is as follows:
+
+     1. A BlockWorkList is created with NewBlockWorkList().  This
+        function instantiates a new BlockWorkList and starts a manager
+        goroutine.  The manager listens on an input channel
+        (manager.newlist) and an output channel (manager.NextItem).
+
+     2. The manager first waits for a new list of requests on the
+        newlist channel.  When another goroutine calls
+        manager.ReplaceList(lst), it sends lst over the newlist
+        channel to the manager.  The manager goroutine now has
+        ownership of the list.
+
+     3. Once the manager has this initial list, it listens on both the
+        input and output channels for one of the following to happen:
+
+          a. A worker attempts to read an item from the NextItem
+             channel.  The manager sends the next item from the list
+             over this channel to the worker, and loops.
+
+          b. New data is sent to the manager on the newlist channel.
+             This happens when another goroutine calls
+             manager.ReplaceItem() with a new list.  The manager
+             discards the current list, replaces it with the new one,
+             and begins looping again.
+
+          c. The input channel is closed.  The manager closes its
+             output channel (signalling any workers to quit) and
+             terminates.
+
    Tasks currently handled by BlockWorkList:
      * the pull list
      * the trash list
 
-   A BlockWorkList is instantiated with NewBlockWorkList(), which
-   launches a manager in a goroutine.  The manager listens on a
-   channel for data to be assigned to it via the ReplaceList() method.
-
-   A worker gets items to process from a BlockWorkList by reading the
-   NextItem channel.  The list manager continuously writes items to
-   this channel.
-
    Example (simplified) implementation of a trash collector:
 
                type DeleteRequest struct {
@@ -26,14 +51,16 @@ package main
 
                // Start a concurrent worker to read items from the NextItem
                // channel until it is closed, deleting each one.
-               go func(list BlockWorkList) {
-                       for i := range list.NextItem {
-                               req := i.(DeleteRequest)
-                               if time.Now() > req.age {
-                                       deleteBlock(req.hash)
+               if diskFull() {
+                       go func(list BlockWorkList) {
+                               for i := range list.NextItem {
+                                       req := i.(DeleteRequest)
+                                       if time.Now() > req.age {
+                                               deleteBlock(req.hash)
+                                       }
                                }
-                       }
-               }(trashList)
+                       }(trashList)
+               }
 
                // Set up a HTTP handler for PUT /trash
                router.HandleFunc(`/trash`,