since the gossip MemberSet has access to Server, it wasn't really necessary to
pass it a Node object when calling Open on it from Cluster. The end goal is to
have it be removed from Cluster entirely, and have it be Opened externally, and
this is a step toward that.
Exposing Node method on Server doesn't really expose any more than was already
there as the same info can be gotten from LocalStatus with a bit of type
casting. I figured adding the method was a little cleaner, and we could collapse
all the functionality when the dust has settled.
The Cluster.open method has been broken into two parts - one of which happens
earlier (at NewServer time), and the other will eventually just be "waiting to
make sure we've joined the cluster". Right now it's calling Memberset.Open, and
then waiting to make sure the cluster has been joined.
pilosa.Server now implements StatusHandler and EventReceiver and needs only
start a gossip memberset. A gossip member set now takes a server as an argument
explicitly and the maze of handlers and receivers and the starting sequence is
somewhat simplified.
Server now trivially implements EventHandler by passing the call along to its
Cluster object which has the actual implementation. This means that less things
will need to refer to cluster.
cluster.open waits for node to join cluster if it is not the coordinator, and
currently this relies on having the http handler able to receive messages, so
handler needs to be started first.
Server initializing happens more in NewServer than Open now - expecting to
continue this trend. goal was to remove remoteClient from Server (since it has a
defaultClient) as well, but we'll have to refactor the client usage in fragment
and frame first.
trying to separate internal an external concerns in pilosa.Server - it should
handle Cluster, Holder, etc. while pilosa/server handles things with external
deps - e.g. Logger, Stats, Handler, etc. Using functional options in
pilosa.Server now.
these were occaisionally referenced elsewhere in the codebase - in all but one
case, there were workarounds that are actually better I think.
In the one case there wasn't I created a single top level DefaultConfig object
which is instantiated with all the default values and can be referred to if
necessary.
There was a bug in fragment.go with the way MaxWritesPerRequest was treated if
it was 0. Elsewhere, 0 meant no limit, but here, it would have caused a division
by 0.
Changed the default metrics provider from "nop" to "none", although "nop" will
still work. Previously, any value other than "statsd" or "expvar" was treated as
"nop", but I've changed this behavior to return an error if an invalid string is
provided. I think this is better behavior, because in the case that someone
bothered to change the default, they were probably interested in actually
getting stats, and might be annoyed when it silently failed.
and it moves the file handling (open/close) out of the main Command and
into the interface implementation. The Logger implementations both have
a `Logger()` method which returns their internal logger (`*log.Logger`).
This is because the gossip setup (memberlist) needs a `*log.Logger` for
its configuration.