[wip] Spawning pool

Time to shave off that final 2-second delay. This PR implements #32 by pre-launching a configured *(by which I mean hardcoded to "3")* set of containers and handing them out to incoming requests. When a container is culled for inactivity, it's scrapped and a new one is launched and added to the pool in its place.

If you hit `orchestrate.py` with a path already set (using a stale link, for example, or an appear.in-style link like #67 implements), you have a personal container created and linked as it happens now.

/cc @rgbkrk so he can see just how terrible this is right now, and suggest embetterment techniques :wink:

- [x] Remove any remaining now-dead code. Container launching should be centralized and managed by the SpawnPool.
- [x] Get culling working again.
- [x] Fix the race condition in the culling routine that causes the pool to grow without bound if the culling interval is shorter than the time that it takes to cull a container.
- [x] Display a friendlier message (meaning, not a stack trace) when the node is out of capacity. A non-200 response code might be useful for upstream load balancing, too. If it's possible, it would be neat to do things like fail over to the next node when 500s are received.
- [x] Since we're using the pool size as an absolute capacity, defaulting to zero is not optimal. `make dev` should probably default to something like 3, maybe.
- [x] Clean out existing containers and proxy entries on restart of `orchestrate.py`.
Ah, this is destructive. We actually keep the original path so that if a user was on, say:

`/user-asdfasdf/notebooks/Welcome.ipynb`

and their container was killed, we bring them back to that old notebook (assuming it exists).