Actions are only scheduled for a valid account, api returns an HTTP 403/503 error otherwise.
Fixes T420.

Summary:
We check account.sync_state to determine validity.
403: invalid
503: connerror

Test Plan:
Test added to tests/api/test_validation.py

Reviewers:
emfree

Reviewed By:
emfree

Subscribers:
charles

Maniphest Tasks:
T420

Differential Revision:
https://review.inboxapp.com/D451
Fix uidvalidity_cb arguments in actions.backends.imap.

Thanks @khamidou for pointing this out.
Use an S3 connection pool for blob saving.

It turns out that initializing a new S3 connection for every object you save to
S3 is really expensive. Instead, maintain a pool of persistent S3 connections.

Using persistent S3 connections is a bit tricky, because the server-side HTTPS
keepalive timeout is short. So having low connection utilization negates the
advantage of pooling. We make a rudimentary attempt to deal with this by always
grabbing the most-recently-used free connection.

This commit also replaces our abuse of the Message object constructor with a
Message.create_from_sync method that's more explicitly for creating a Message
object in the mailsync context. We save message parts asynchronously for
greater performance -- we don't really need to do this when we're saving to
local disk, but it helps validate the logic for when we actually want to do so.

Finally, also rework the Blob interface a bit, mostly by replacing the
Blob.data setter with explicit Blob.save_data() and Blob.async_save_data()
methods. It wasn't great to have the innocent-looking `part.data = data`
actually doing a whole bunch of I/O and whatnot under the hood.