Stream Cluster

Write a consistent ESDB stream to a cluster of machines. We use the raft protocol for writes, reads are from the local node's log, so it's possible they may be stale.

To start a cluster:

    go run cmd/esdb-node.go -p 4001 tmp/1
    go run cmd/esdb-node.go -p 4002 -join localhost:4001 tmp/2
    go run cmd/esdb-node.go -p 4003 -join localhost:4001 tmp/3

View the state of the cluster:

    curl -i localhost:4002/cluster/status

To add events (can be called on any running node):

    curl -XPOST -i localhost:4001/events -d "{\"body\":\"ab\",\"indexes\":{\"a\":\"b\"}}"
    curl -XPOST -i localhost:4001/events -d "{\"body\":\"ac\",\"indexes\":{\"a\":\"c\"}}"

To iterate through all events (will return "ab" and "ac"):

    curl "localhost:4001/events?limit=20"

To scan an index (will return just "ab"):

    curl "localhost:4001/events?index=a&value=b&limit=20"

## TODO:

1. ~~Compact/snapshot the raft log after every stream log rotation.~~
1. ~~Don't allow reads while recovering from logs.~~
1. ~~Process for recovering missing stream log (if a node is down or disconnected for an entire rotation, once the raft log is compacted, it'll need to recover the closed stream log from another node before booting up)~~
1. Don't allow reads while disconnected from leader??? Figure out needed consistency of reads.
1. Process for removing old stream logs from the cluster (after they've been merged into coldstorage, etc)
1. ~~Consistency testing.~~
1. ~~Performance testing (writes/s, optimize log rotation size, etc).~~
1. ~~Production data testing.~~