-
Notifications
You must be signed in to change notification settings - Fork 14
Changing Timeouts
Before reading further, it is important to point out the inherent risks of using client request timeouts.
Versions 3.1.3 and below have read timeout defaulted to 1 minute, which has potential risk (see below).
Versions 3.2.0 and above are defaulted to off.
The S3 protocol does not provide any transaction semantics outside of a single request. With this in mind, if a client PUT request times out, it is very possible (likely in fact) that this request will eventually execute on the server side. So whenever you use a client timeout, you must be aware of the possibility of delayed execution on any timed out request. This could lead to lost updates. For example, imagine the following scenario:
- client executes
PUT /bucket1/object1
{X}
- request times out
- client retries
PUT /bucket1/object1
{X}
- request succeeds
- client sends update
PUT /bucket1/object1
{X2}
- request succeeds
- original
PUT
completes execution on ECS - state of
/bucket1/object1
is now{X}
(the update{X2}
is lost)
One way to mitigate this risk is to use pre-conditions on your requests as an optimistic lock. For example, in the scenario above, assuming you know that the original PUT request for /bucket1/object1
will create the object (it should not exist prior), then you can set the If-None-Match
header to "*
". This pre-condition states that the request should only execute if the object does not exist. If we had applied that precondition to the first PUT above, then when it finally executes on ECS (step 7), it would fail because the object has already been created, and {X2}
would remain the current state as expected.
Similarly, if you cache the ETag of the object after each PUT, you can set the If-Match
header to that ETag on subsequent PUTs. This pre-condition states that the request should only execute if the object is in the state you expect it to be (having that ETag or MD5). In the example above, we could add that pre-condition to step 5, and if that step times out, it will only execute on ECS if the object hasn't changed since we first sent the request. This would avoid any lost updates that happen after {X2}
.
Versions 3.1.3 and below:
The default read timeout for the client is 60 seconds and the default connect timeout is 15 seconds. In some cases, you may need to increase that (for example, if you are issuing a large multi-delete call or a call that may take longer than 60 seconds). To change the timeouts, set the following properties on the S3Config
instance passed to the client constructor:
S3Config s3Config = ...
// set connect timeout:
s3config.setProperty(ClientConfig.PROPERTY_CONNECT_TIMEOUT, 30000); // value is MS
// set read timeout (for long-running calls) - set to 0 to disable:
s3config.setProperty(ClientConfig.PROPERTY_READ_TIMEOUT, 300000); // value is MS
S3Client s3Client = new S3JerseyClient(s3Config);
Versions 3.2.0 and above (default read timeout is disabled):
S3Config s3Config = ...
// set connect timeout:
s3config.setConnectTimeout(30000); // value is MS
// set read timeout (for long-running calls) - set to 0 to disable:
s3config.setReadTimeout(300000); // value is MS
S3Client s3Client = new S3JerseyClient(s3Config);