Yesterday, I was able to get player updates in my (fab) game stored in a CouchDB backend thanks to node-couchdb. Today, I hope to move the entire store over to CouchDB.
First up, I need to be able to drop players:
  drop_player: function(id) {
    Logger.info("players.drop_player " + id);
    this.faye.publish("/players/drop", id);
    this.get(id, function(player) {
      Logger.debug("[players.drop_player] " + inspect(player));
      if (player) db.removeDoc(id, player._rev);
    });
  }To delete in CouchDB, I need the current revision of the document.  I use the get() method from last night to grab the current document, then remove it immediately.  I could keep the revision ID in the local store to get around the lookup/then delete.  I will worry about doing that when this proves to be a bottleneck.Up next, I need to rework the idle timeout code a bit. I had been storing the idle timeout directly on the player objects in the local store (
this._):  idle_watch: function(id) {
    if (this._[id].idle_timeout) {
      clearTimeout(this._[id]].idle_timeout);
    }
 
    var self = this;
    this._[id].idle_timeout = setTimeout(function() {
       Logger.info("timeout " + id +"!");
       self.drop_player(id);
    }, 30*60*1000);
 
    this._[id].idle_watch_started = "" + (new Date());
   }Since I am no longer storing data locally, I need to create a new local store for these timeouts.  Easy enough:  timeouts: { },
  idle_watch: function(id) {
    if (this.timeouts[id])
      clearTimeout(this.timeouts[id]);
    var self = this;
    this.timeouts[id] = setTimeout(function() {
      Logger.info("timeout " + id +"!");
      self.drop_player(id);
    }, 30*60*1000);
  }The timeouts are now stored in the timeouts attribute in my players object, which leaves very little still relying on the old local store.  After replacing a couple more individual gets from the local store, I am left with only one more local store reference—a lookup of all players in a faye subscription:     this.faye.subscribe("/players/query", function(q) {
      var ret = [];
      for (var id in self._) {
        ret.push(self._[id].status);
      }
      self.faye.publish("/players/all", ret);
    });As with everything else in node-couchdb, a lookup of all documents in CouchDB is done via callback:  all: function(callback) {
    return db.allDocs({include_docs:true}, function(err, docs) {
      callback(docs.rows.map(function(row) {return row.doc;}));
    });
  }I use {include_docs:true} to pull back the player documents rather than just the meta data that is normally returned.  Similarly, I map those results to return just the player documents (no meta data).  With that, I need to convert the faye subscription to use the callback:  all: function(callback) {
    return db.allDocs({include_docs:true}, function(err, docs) {
      callback(docs.rows.map(function(row) {return row.doc;}));
    });
  }And finally, I can remove the local store entirely.  I am still storing timeouts locally, but that is a code timeout, so there is really no choice in the matter. Now that I think about it, I ought to be able to save the timeout time in the CouchDB store.  If I do that, I could restore the software timeout after a server restart.  I will pick back up with that tomorrow.Day #209
No comments:
Post a Comment