/// <summary> /// The connection establishment is attempted multiple times and is given up /// only on the last failure. /// </summary> /// <remarks> /// The connection establishment is attempted multiple times and is given up /// only on the last failure. Instead of connecting with a timeout of /// X, we try connecting with a timeout of x < X but multiple times. /// </remarks> /// <exception cref="System.IO.IOException"/> private void Connect(URLConnection connection, int connectionTimeout) { int unit = 0; if (connectionTimeout < 0) { throw new IOException("Invalid timeout " + "[timeout = " + connectionTimeout + " ms]" ); } else { if (connectionTimeout > 0) { unit = Math.Min(UnitConnectTimeout, connectionTimeout); } } long startTime = Time.MonotonicNow(); long lastTime = startTime; int attempts = 0; // set the connect timeout to the unit-connect-timeout connection.SetConnectTimeout(unit); while (true) { try { attempts++; connection.Connect(); break; } catch (IOException ioe) { long currentTime = Time.MonotonicNow(); long retryTime = currentTime - startTime; long leftTime = connectionTimeout - retryTime; long timeSinceLastIteration = currentTime - lastTime; // throw an exception if we have waited for timeout amount of time // note that the updated value if timeout is used here if (leftTime <= 0) { int retryTimeInSeconds = (int)retryTime / 1000; Log.Error("Connection retry failed with " + attempts + " attempts in " + retryTimeInSeconds + " seconds"); throw; } // reset the connect timeout for the last try if (leftTime < unit) { unit = (int)leftTime; // reset the connect time out for the final connect connection.SetConnectTimeout(unit); } if (timeSinceLastIteration < unit) { try { // sleep the left time of unit Sleep(unit - timeSinceLastIteration); } catch (Exception) { Log.Warn("Sleep in connection retry get interrupted."); if (stopped) { return; } } } // update the total remaining connect-timeout lastTime = Time.MonotonicNow(); } } }
private static void SetTimeouts(URLConnection connection, int socketTimeout) { connection.SetConnectTimeout(socketTimeout); connection.SetReadTimeout(socketTimeout); }