feat(governor): rate limit by project

This patch adds support to eom:governor for rate limiting at the
tenant level.

This is accomplished by adding a new configuration option,
`project_rates_file`. This points to a JSON file that is identical to
the format used for `rates_file`, but also requires the 'project'
field to be present.

Some refactoring was undertaken to make this change easier to
test. Namely:

- applies_to is no longer a method of Rate
- the rate matching logic was pulled into a function rate_matches
feat(governor): leaky bucket algorithm

This PR replaces the existing governor's double-bucket approach with a
leaky bucket implementation of rate limiting.

This leads to a simple implementation to use and reason
about. Furthermore, the following concepts were removed:

- Cache object: use raw dictionaries instead
- period_sec: no longer relevant, as we don't context-switch
- max_sleep_sec: no longer relevant. Max sleep implicit on target rate
- node_count: removed. Makes configuring individual nodes less intuitive

Drain velocity has been added. It may yet be removed. It might be more
reasonable to define a drain acceleration factor and use a combination
of the delta since the last request and the target rate to determine
how much to drain per request from the bucket.

A simplification of the sleep_for function is provided that determines
how much to sleep based on:

(count / limit) * sleep_offset

This makes it very easy to hand-calculate how much one would sleep if
the soft limit is exceeded and how sleep_offset works with that.

This implementation is fully distributed.
fix(gov): replace hard limit sleep_for w/ sleep
fix(gov): several minor issues

* rename: sleep_offset -> sleep_offset
* prune: all the remaining node_count refs
* clarify: increment per request
* optimize: cache access
fix(governor): NameError and sleep durations

Missed defining count in one branch for calc_sleep.

Took a close look at sleep durations returned, and it was possible to
sleep longer when soft limited than when hard limited. Fixed by using
hard limit in sleep_for and considering sleep_factor in hard limit
scenario.

For reference, sleep algorithm is currently:

calc_sleep :: Float -> Float -> Float -> Float -> Float
calc_sleep count slimit hlimit factor
  | count < slimit = 0
  | count <= slimit && count < hlimit = (count / hlimit) * factor
  | count > hlimit = 1.0 * factor
feat(governor): simpler rate limiting

While preserving the leaky bucket algorithm, the throttling aspect has
been greatly simplified. The new variant places the burden of
responding to backpressure on connected clients.

New configuration:
- throttle_milliseconds

Removed configuration:
- sleep_factor

Changed configuration:
- soft_limit: gone
- hard_limit -> limit

Changed names:
- _create_calc_sleep -> _create_limiter
- calc_sleep -> check_limit
tests(governor): update for new algorithm

Updates and refactors tests for great good.
feat(Centralized Redis Governer):
This patch aims to replace the in-memory dictionary logic with a centralised
Redis instance, that increments the counter for the Project-ID for every
request and throws a HardLimit Exception if the Client goes over the
stipulated limits.
fix(network): lesser network hops
Use hmgets instead of individual hgets
fix() : change app wrapping

This allows sending an connection handler, along with the app to wrap
The unit tests are working with this patch
fix(tests): Add fakeredis test requirement
fix(exception handling): Redis Failures

If for some reason, there is a failure while connecting to Redis,
the exceptions are written to the log and continues as if there was no
rate limits
fix(redis calls) : Reduced redis calls
feat(example): Add example for governor wrap
update(requirements) : add dependencies