You can generally find the latest copy of the web UI running at http://iron-man.local:5000/.

Meeting notes (8/30):

Types:
    There are several object the will need to reference. These types allow them
    to do so. Probably these types are going to be human readable. It goes
    without saying that any function that takes one of these as an argument
    will error if the identifier references something we don't know about.
    Furthermore not knowing about can mean that either it hasn't yet been
    created or it's been created and we haven't caught wind of it due to
    network effects. However if we've heard of something but it's not reachable
    that's a different kind of error and it's discussed specifically.
    Excepting creation commands which will error in the opposite case.

    - datacenter_id
    - machine_id
    - namespace_id
    - shard_id - these won't be human readable
    - shard_definition_t - what goes in a shard (for example a range of keys) this type is polymorphic
    - timestamped - wraps a piece of data to inform how up to date that data is

    - cluster_error

Actions (initiated by the user):

    Datacenter management:
        - create_datacenter :: (datacenter_id) -> Maybe cluster_error
            Fails:
                - datacenter_id is already in use
                - could also fail if there's some sort of quorum needed to create a datacenter
        - reassign_datacenter :: (namespace_id, datacenter_id) -> Maybe cluster_error
            Fails:
                - Machine is unreachable.
                - Datacenter quorum is unreachable
    Pick a primary datacenter for a namespace
        - set_primary :: (namespace_id, datacenter_id, bool force) -> Maybe cluster_error
            Fails:
                - Old primary inaccessible. (Can be overriden with force).
                - datacenter inaccessible.
    Configure namespace replica counts per datacenter
        - set_replica_counts :: (namespace_id, datacenter_id, int, bool force) -> Maybe cluster_error
            This function actually has no effect until you call replenish_replicas
            Fails:
                - Datacenter unreachable.
                - Namespace unreachable
                    In order to bring up a replica we need to be able to see another replica for that namespace.
                    This can just be a warning, since we can just accept the command and bring them up to speed when a connection is made.
                - Would extinct namespace (Can be overriden with force).
                    Setting the number of replicas of a namespace to 0 for all
                    datacenters requires a force command. With a force command
                    it's equivalent to deleting the namespace. I'm not quite
                    sure about that last part, there's maybe a use case for
                    having a namespace with no replicas up but still having the
                    metadata... that seems kind of far fetched to me(joe)
                    though.

        - replenish_replicas :: (namespace_id, Optional datacenter_id) -> Maybe cluster_error
            Note: This brings per datacenter replica counts in line with the
            set values as much as possible. They could be out of sync with
            those values either because of failures or explicit changes by the
            user.
            Fails:
                - Namespace unreachable.
                - Datacenter unreachable - would extinct namespace.
                    There's a bit of complexity in when this errors, Under some
                    conditions we can safely replenish one datacenters replicas
                    even if the others are offline (assuming it has a way to
                    reach the namespace and get the data). However with
                    some changes in distribution this would extinct the
                    namespace in which case we can't do it.
    Namespace multitenancy:
        - set_cache_quota :: (namespace_id, Int) -> Maybe cluster_error
            Fails:
                - Namespace unreachable.
        - set_disk_quota :: (namespace_id, Int) -> Maybe cluster_error
            Fails:
                - Namespace unreachable.
    Bring machines, namespaces, and datacenters up / down
        - bring_down_machine :: (machine_id, bool force) -> Maybe cluster_error
            Fails:
                - Machine unreachable.
                - Would make namespace unreachable (Can be overriden by force)

        - bring_down_namespace :: (namespace_id) -> Maybe cluster_error
            Fails:
                - Cannot reach primary for namespace.

        - bring_down_datacenter :: (datacenter_id, bool force) -> Maybe cluster_error
            Fails:
                - Cannot reach datacenter.
                - Would make namespace unreachable (Can be overriden by force)

    Create / delete namespace
        - create_namespace :: (namespace_id, meta_data, datacenter_id) :: -> Maybe cluster_error
            meta_data is the stuff we'll need to setup the namespace, one thing
            is what type of protocol this namespace will be providing (riak,
            memcached etc). datacenter_id is the datacenter that will house 
            the master (and an initial replica).
            Fails:
                namespace_id already in use.

        - delete_namespace :: (namespace_id) -> Maybe cluster_error
            Fails:
                namespace_id unreachable.

    Shard manipulation shards:
        - more_shards :: (namespace_id) -> Maybe cluster_error
            Fails:
                - Namespace unreachable.

        - delete_shard :: (namespace_id, shard_id) -> Maybe cluster_error
            Note deleting a shard may require modifications to other shards (someone has to take on the orphaned data).
            Fails:
                - Namespace unreachable.
                - Would extinct namespace. (Every namespace must have at least one shard in it.)

        - fewer_shards :: (namspace_id) -> Maybe cluster_error
            This is just a delete shard in which we select the shard (in a maybe intelligent way).
            Fails like delete_shard.

        - report_shard_balances :: (namespace_id) -> Either cluster_error [(shard_id, timestamped shard_definition_t, timestamped float portion_contained)]
            shard_definition_t is something like the boundaries for range shards.
            Fails:
                - namespace unreachable.

        - rebalance_shards :: (namepspace_id, [(shard_id, shard_definition_t)]) -> Maybe cluster_error
            Fails:
                - namespace unreachable.
                - Shard definition would orphan data. (The shard defintions are
                    not a partition of the key space, except that there can be
                    empty shard_definition_ts).

        - suggest_shard_rebalance  :: (namespace_id) -> Either cluster_error [(shard_id, shard_definition_t, portion_contained)]
            Fails:
                - namespace unreachable.

    Getting information about the state of the database: I'm just going to lay
    out the schema of the data and then you can query it however you want, I
    don't think we'll actually query these with a language just figure out
    which queries we want and give them names.

    datacenter:                     datacenter_id | metadata 
    namespace:                      namespace_id | metadata
    namespace_replica_goal:         Foreign datacenter_id | Foreign namespace_id | int
    machine:                        machine_id | Foreign datacenter_id | metadata
    shard_definition:               shard_id | shard_definition_t | Foreign namespace_id
    shard_replica:                  Foreign shard_id | Foreign shard_id


Actions (performed automatically):

    When the master goes down, automatically choose a new master by consistent logic
    Whenever you have a new replica, perform a backfill
    When a node goes down and comes back up, perform a backfill



States for a mirror:

    Down
    Disconnected from master
    Backfilling
    Active



In the case of a netsplit: if the primary count ≠ 1, upon reconnect fail all queries until manual administrator action is taken0.
