Pull cache test patterns into reusable contextmanagers
Multiprocessing Cache Check and Write

This is a slight refactor of a change we've been using internally at foursquare for a few months.

Avoiding recompression during downloads (https://rbcommons.com/s/twitter/r/1233/) reduces the amount of this work we do, while this change is about doing it faster. Most cache work is CPU-bound gzipping of the tarballs, so moving cache fetch/decompression and compression/upload to into subprocesses improves multicore utilization.

This is done using a multiprocessing.Pool, passing ArtifactCaches and the arguments to their methods to subprocesses (whichi is why they were made pickle-friendly in previous changes).

Additionally, we discovered (through a very painful debugging process) that python's zlib bindings use a global static lock which, if in use by any thread when a subprocess is created via fork(), can be inherited my children in a locked state meaning, the child will deadlock if it later tries to use zlib. This is why the pools are created early in run_tracker rather than as-needed, and is discussed in the comment on SubprocPool in worker_pool.py.