Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I've been struggling with this problem for a while, running long-running processes which read large amount of data from S3. I decided to post my solution here, for posterity.</p> <p>First of all, I'm sure the hack pointed to by @Glenn works, but I chose not to use it because I consider it intrusive (hacking httplib) and unsafe (it blindly returns what it got, i.e. <code>return e.partial</code>, despite the fact it can be real-error-case).</p> <p>Here is the solution I finally came up with, which seems to be working.</p> <p>I'm using this general-purpose retrying function:</p> <pre><code>import time, logging, httplib, socket def run_with_retries(func, num_retries, sleep = None, exception_types = Exception, on_retry = None): for i in range(num_retries): try: return func() # call the function except exception_types, e: # failed on the known exception if i == num_retries - 1: raise # this was the last attempt. reraise logging.warning('operation failed (%s) with error [%s]. will retry %d more times', func, e, num_retries - i - 1) if on_retry is not None: on_retry() if sleep is not None: time.sleep(sleep) assert 0 # should not reach this point </code></pre> <p>Now, when reading a file from S3, I'm using this function, which internally performs retries in case of <code>IncompleteRead</code> errors. Upon an error, before retrying, I call <code>key.close(fast = True)</code>.</p> <pre><code>def read_s3_file(key): """ Reads the entire contents of a file on S3. @param key: a boto.s3.key.Key instance """ return run_with_retries( key.read, num_retries = 3, sleep = 0.5, exception_types = ( httplib.IncompleteRead, socket.error ), # close the connection before retrying (fast=True so it doesn't attempt to read remaining) on_retry = lambda: key.close(fast = True) ) </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload