streamer: Pass streamer events through the queue

This commit makes it possible for multiple worker processes to receive
the streamer events by passing them through an external queue.

As before, an `h.events.AnnotationEvent` subscriber is responsible for
serializing events. It now publishes them to an external NSQ topic. The
details of connection to NSQ are managed by the `h.queue` module.

When the streamer module is included by pyramid, it will start up a pair
of greenlets which are responsible for deserializing and handling the
events pulled from the NSQ topic. One of these opens a persistent TCP
connection to NSQ and receives messages, pushing them onto an internal
queue structure. The second reads from the internal queue structure, and
broadcasts the events to active websocket sessions as appropriate.

A final point of explanation: NSQ sorts messages into "topics", which
serve as a named queue, and "channels", which are associated with a
specific topic. Topics and channels differ thus:

- each message sent to a topic is copied to every channel (i.e. fanout)
- if multiple clients connect to the same channel, incoming messages
  will be shared between those clients in a round-robin (i.e. they are
  worker queues)

As a result, each web worker connects to NSQ using a unique channel
name, ensuring that each queue reader gets copies of every message
published to the topic.

At the moment, we use ephemeral channels in order to avoid messages
backing up in NSQ for web workers that have long since ceased to exist.
This does mean that in the event of a network partition between web
worker and NSQ, some messages may be lost and not relayed to websocket
clients connected to that worker.
Don't update mappings by default in production

Also adds an option to development.ini with instructions to do the same
if running multiple workers in development.
queue: Make queue implementation swappable

This commit makes it possible to swap out the queue implementation for
anything satisfying h.queue.interfaces.IQueueHelper, i.e. providing a
"get_reader" and "get_writer" methods.
queue: Add a thread-local queue implementation

This adds an implementation of a queue interface that mirrors the NSQ
reader/writer paradigm but uses thread-local gevent queues to pass
messages around.

Changes development.ini to default to this local queue implementation.
Refactor the queued streamer a bit

This change refactors the queued streamer to hopefully make it a bit
simpler in a few places.

- Rather than having `get_reader` and `get_writer` be both request
  methods and configurator directives just use request methods. This
  eliminates the nasty partial stuff.
- Pass the settings to the IQueueHelper implementation rather than
  on every call to `get_reader` or `get_writer`.
- Store the queue as a class attribute of the `StreamerSession`.
- Track active session instances with a `WeakSet`.
- Start the reader when the first client connects.
- Skip including the streamer module entirely when the feature is
  disabled, by moving that check to the h module include.
- Register an instance of `IQueueHelper` rather than the class itself.
  Otherwise, we would name the interface `IQueueHelperClass`. Add
  the zope.interface.implements decorator to the implementations to
  make this more clear. Looking up a utility by an interface should
  always give an instance of something which implements that interface,
  not a factory or constructor for it.
queue: Interface definitions don't take self

http://docs.zope.org/zope.interface/README.html#defining-interfaces
streamer: Add test demonstrating reader not started
streamer: Don't shadow pyramid_sockjs queue

This class attribute was shadowing an internal queue used by
`pyramid_sockjs` and as a result the queue reader was never being
started in `StreamerSession#on_open()`.

See: https://github.com/fafhrd91/pyramid_sockjs/blob/d5bf8a9/pyramid_sockjs/session.py#L49
Switch to ws4py

Since pyramid_sockjs seems pretty unmaintained, having fallen behind
gevent-websocket quite a bit, and there don't seem to be any actively
maintained pyramid websocket integration libraries, switch to using
ws4py directly.

This change drops support for non-native websockets. As a result, we
have to do our own JSON decoding of the messages.

We also switch to a `gevent.pywsgi` based worker of our own. This
worker combines the gevent_pywsgi worker from Gunicorn with the
gevent helpers from ws4py that cleanly shutdown sockets on server
termination.
streamer: Fix failing WebSocket test