internal void getObject(IAmazonS3 amazonS3, S3ObjectRequest request) { Exception exception = null; long length = request.End - request.Start + 1; GetObjectRequest getObjectRequest = new GetObjectRequest() { BucketName = request.BucketName, Key = request.Key, ByteRange = new ByteRange(request.Start, request.End) }; for (int i = 0; i <= _retryRequests; i++) { try { GetObjectResponse response = amazonS3.GetObject(getObjectRequest); using (BufferedStream input = new BufferedStream(response.ResponseStream)) { byte[] buffer = new byte[length]; int current = 0; int bytesRead = 0; int count = buffer.Length; while ((bytesRead = input.Read(buffer, current, count)) > 0) { current += bytesRead; count -= bytesRead; } _s3Reader.addCache(request.Start, buffer); } response.Dispose(); exception = null; return; } catch (Exception ex) { exception = ex; //! exponential backoff //! wait seconds 1, 2, 4, 8, 16, 32, 64 .... int millisecondsTimeout = (2 ^ i) * 1000; Thread.Sleep(millisecondsTimeout); } } if (exception != null) { throw exception; } }
internal void Execute() { while (_waitEvent) { S3ObjectRequest request = null; while ((request = getNextPartRequest()) != null) { downloadPart(request); if (_lastException != null) { lock (_s3Reader.WAIT_FOR_COMPLETION_LOCK) { Monitor.Pulse(_s3Reader.WAIT_FOR_COMPLETION_LOCK); } return; } } } }
int addRequestToDownload(int count) { lock (QUEUE_ACECSS_LOCK) { int n = 0; while (n < count) { if (_objectRequests.Count == 0) { break; } S3ObjectRequest request = _objectRequests.Dequeue(); _objectRequestToDownload.Enqueue(request); addCache(request.Start, null); n++; } return(n); } }
internal void downloadPart(S3ObjectRequest request) { Exception exception = null; try { getObject(_s3Client, request); exception = null; return; } catch (ThreadAbortException) { throw; } catch (Exception ex) { exception = ex; } if (exception != null) { _lastException = exception; } }