
FUSE main enqueues notifications of:

 * 'open' (path)
 * 'release' (path)
 * 'rename' (from, to)
 * 'mknod' (path, mode)
 * 'write' (path, offset, nbyte)
 * 'create' (path, mode)
 * 'unlink' (path)

The queue is maintained by a WorkspaceManager.

    class WorkspaceManager {

    public:
        void setWorkspaceLocation(string path);

        // If set, we'll use this changelist for all workspace operations
        void setChangelist(string changelist);

        void enqueue(Notification n);

        // The length of time we'll wait until we attempt to resolve any
        // file system changes
        time_t pauseAmount();

        // When true, there's work to do in the queue
        bool processing() const;

        // If everything's OK, returns "OK", otherwise, prints errors
        string status() const;

    private:
        // See our 'update algorithm'

        // Called back on a timer we initiate whenever enqueue() is called.
        void check();

        // Calls p4 reconcile
        void reconcile();
    };

## Update algorithm

* If the last notification happened before our pauseAmount, retrigger our timer
  to call check()

* If we're done waiting, call process()

What we do in process() depends on the current state of the system.