diff --git a/BaseSpace.SDK.Tests/BaseSpace.SDK.Tests.csproj b/BaseSpace.SDK.Tests/BaseSpace.SDK.Tests.csproj
index a5ab4f4..fe85b21 100644
--- a/BaseSpace.SDK.Tests/BaseSpace.SDK.Tests.csproj
+++ b/BaseSpace.SDK.Tests/BaseSpace.SDK.Tests.csproj
@@ -42,6 +42,9 @@
$(SolutionDir)\packages\log4net.1.2.10\lib\2.0\log4net.dll
+
+ ..\packages\Moq.4.2.1409.1722\lib\net40\Moq.dll
+
False
$(SolutionDir)\packages\ServiceStack.Common.3.9.35\lib\net35\ServiceStack.Common.dll
diff --git a/BaseSpace.SDK.Tests/JsonWebClientTests.cs b/BaseSpace.SDK.Tests/JsonWebClientTests.cs
index 96c3dff..99fba71 100644
--- a/BaseSpace.SDK.Tests/JsonWebClientTests.cs
+++ b/BaseSpace.SDK.Tests/JsonWebClientTests.cs
@@ -1,6 +1,9 @@
using System;
+using System.Diagnostics;
using Illumina.BaseSpace.SDK.Deserialization;
+using Illumina.BaseSpace.SDK.ServiceModels;
using Illumina.BaseSpace.SDK.Types;
+using Moq;
using Xunit;
namespace Illumina.BaseSpace.SDK.Tests
@@ -8,6 +11,61 @@ namespace Illumina.BaseSpace.SDK.Tests
public class JsonWebClientTests
{
+ [Fact]
+ public void RequestOptionsAreProperlyUsed()
+ {
+ var client = new BaseSpaceClient(new BaseSpaceClientSettings()
+ {
+ BaseSpaceApiUrl = "https://api.basespace.illumina.com",
+ Authentication = new OAuth2Authentication("xxxxx"),
+ TimeoutMin = .00001
+ });
+
+ var sw = Stopwatch.StartNew();
+ try
+ {
+ var ass = client.GetAppSession(new GetAppSessionRequest("xxxx"), new RequestOptions(6,.1));
+ }
+ catch (Exception)
+ {
+
+ }
+ sw.Stop();
+
+ Assert.InRange(sw.ElapsedMilliseconds,0,10*1000);
+
+ }
+
+
+ [Fact(Skip = "disabled since it needs token and session")]
+ public void CanRespawnClientAtEachRetry()
+ {
+ var setting = new BaseSpaceClientSettings()
+ {
+ BaseSpaceApiUrl = "https://api.cloud-test.illumina.com",
+ Authentication = new OAuth2Authentication("xxxxx"),
+ TimeoutMin = .0000000001
+ };
+
+ var client = new Mock(setting, null);
+ int retry = 0;
+ client.Setup(c => c.RespawnClient()).Callback(() =>
+ {
+ // this should occur only once and because of the ridiculous timeout
+ Assert.Equal(1, ++retry);
+
+ // respawn the client with a normal timeout
+ // should be proof that the newly created client
+ // is used on second retry
+ client.Object._clientFactoryMethod();
+ client.Object.client.Timeout = TimeSpan.FromMinutes(1);
+ });
+
+ var ass = client.Object.Send(new GetAppSessionRequest("xxxxx"), new RequestOptions(6, .1));
+ }
+
+
+
[Fact]
public void CanDeserializeARunCompactReference()
{
diff --git a/BaseSpace.SDK.Tests/packages.config b/BaseSpace.SDK.Tests/packages.config
index f3b4699..7041800 100644
--- a/BaseSpace.SDK.Tests/packages.config
+++ b/BaseSpace.SDK.Tests/packages.config
@@ -2,6 +2,7 @@
+
diff --git a/BaseSpace.SDK/Infrastructure/BaseSpaceClientSettings.cs b/BaseSpace.SDK/Infrastructure/BaseSpaceClientSettings.cs
index 9489b5e..c5a23e2 100644
--- a/BaseSpace.SDK/Infrastructure/BaseSpaceClientSettings.cs
+++ b/BaseSpace.SDK/Infrastructure/BaseSpaceClientSettings.cs
@@ -1,8 +1,9 @@
namespace Illumina.BaseSpace.SDK
{
public class BaseSpaceClientSettings : IClientSettings
- {
- public const uint DEFAULT_RETRY_ATTEMPTS = 6;
+ {
+ public const uint DEFAULT_RETRY_ATTEMPTS = 6;
+ public const uint DEFAULT_RETRY_POWER_BASE = 5;
public const string DEFAULT_WEBSITE = "https://basespace.illumina.com";
@@ -48,6 +49,6 @@ public BaseSpaceClientSettings()
public IAuthentication Authentication { get; set; }
- public int TimeoutMin { get; set; }
+ public double TimeoutMin { get; set; }
}
}
diff --git a/BaseSpace.SDK/Infrastructure/JsonWebClient.cs b/BaseSpace.SDK/Infrastructure/JsonWebClient.cs
index 440c5f4..e5594db 100644
--- a/BaseSpace.SDK/Infrastructure/JsonWebClient.cs
+++ b/BaseSpace.SDK/Infrastructure/JsonWebClient.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Net;
+using System.Runtime.Remoting.Messaging;
using System.Web.Util;
using Common.Logging;
using Illumina.BaseSpace.SDK.Deserialization;
@@ -15,16 +16,27 @@ namespace Illumina.BaseSpace.SDK
{
public class JsonWebClient : IWebClient
{
- private readonly JsonServiceClient client;
- private readonly JsonServiceClient clientBilling;
+ internal JsonServiceClient client;
+ private JsonServiceClient clientBilling;
- private readonly ILog logger;
+ private ILog logger;
- private readonly IClientSettings settings;
+ private IClientSettings settings;
+
+ public virtual void RespawnClient()
+ {
+ if (_clientFactoryMethod != null)
+ _clientFactoryMethod();
+ }
+
+
+ internal readonly Action _clientFactoryMethod;
public JsonWebClient(IClientSettings settings, IRequestOptions defaultOptions = null)
{
+ _clientFactoryMethod = () =>
+ {
if (settings == null)
{
throw new ArgumentNullException("settings");
@@ -53,6 +65,9 @@ public JsonWebClient(IClientSettings settings, IRequestOptions defaultOptions =
clientBilling = new JsonServiceClient(settings.BaseSpaceBillingApiUrl);
clientBilling.LocalHttpWebRequestFilter += WebRequestFilter;
+ };
+
+ _clientFactoryMethod();
}
static JsonWebClient()
@@ -108,10 +123,13 @@ public TReturn Send(AbstractRequest request, IRequestOptions o
TReturn result = null;
options = options ?? DefaultRequestOptions;
- var clientForRequest = PickClientForApiName(request.GetApiName());
- RetryLogic.DoWithRetry(options.RetryAttempts, request.GetName(),
- () => result = request.GetSendFunc(clientForRequest)(), logger);
+ RetryLogic.DoWithRetry(options.RetryAttempts, request.GetName(), () => result = request.GetSendFunc(PickClientForApiName(request.GetApiName()))(), logger,
+ retryIntervalBaseSecs:options.RetryPowerBase,retryHandler: (exc) =>
+ {
+ RespawnClient();
+ return RetryLogic.GenericRetryHandler(exc);
+ });
return result;
}
catch (WebServiceException webx)
diff --git a/BaseSpace.SDK/Interfaces/IClientSettings.cs b/BaseSpace.SDK/Interfaces/IClientSettings.cs
index 734a168..a349bc8 100644
--- a/BaseSpace.SDK/Interfaces/IClientSettings.cs
+++ b/BaseSpace.SDK/Interfaces/IClientSettings.cs
@@ -19,6 +19,6 @@ public interface IClientSettings
IAuthentication Authentication { get; }
- int TimeoutMin { get; }
+ double TimeoutMin { get; }
}
}
diff --git a/BaseSpace.SDK/Interfaces/IRequestOptions.cs b/BaseSpace.SDK/Interfaces/IRequestOptions.cs
index 772c20f..749aea8 100644
--- a/BaseSpace.SDK/Interfaces/IRequestOptions.cs
+++ b/BaseSpace.SDK/Interfaces/IRequestOptions.cs
@@ -1,8 +1,13 @@
namespace Illumina.BaseSpace.SDK
{
- public interface IRequestOptions
+ public interface IRetryOptions
+ {
+ uint RetryAttempts { get; }
+ double RetryPowerBase { get; }
+ }
+
+ public interface IRequestOptions: IRetryOptions
{
- uint RetryAttempts { get; }
}
}
diff --git a/BaseSpace.SDK/Properties/AssemblyInfo.cs b/BaseSpace.SDK/Properties/AssemblyInfo.cs
index 16cc3b6..7ba1d01 100644
--- a/BaseSpace.SDK/Properties/AssemblyInfo.cs
+++ b/BaseSpace.SDK/Properties/AssemblyInfo.cs
@@ -35,5 +35,5 @@
[assembly: AssemblyVersion("1.0.0.9")]
[assembly: AssemblyFileVersion("1.0.0.9")]
//[assembly: InternalsVisibleTo("Illumina.BaseSpace.SDK.Private")] //Sujit: had to comment this out to allow strong sigining TV for BaseSpaceDownloader
-//[assembly: InternalsVisibleTo("Illumina.BaseSpace.SDK.Tests")] //Sujit: had to comment this out to allow strong sigining TV for BaseSpaceDownloader
+[assembly: InternalsVisibleTo("Illumina.BaseSpace.SDK.Tests")] //Sujit: had to comment this out to allow strong sigining TV for BaseSpaceDownloader
//[assembly: InternalsVisibleTo("Illumina.BaseSpace.SDK.Private.Tests")]//Sujit: had to comment this out to allow strong sigining TV for BaseSpaceDownloader
diff --git a/BaseSpace.SDK/Types/RequestOptions.cs b/BaseSpace.SDK/Types/RequestOptions.cs
index e63be97..c92d5a0 100644
--- a/BaseSpace.SDK/Types/RequestOptions.cs
+++ b/BaseSpace.SDK/Types/RequestOptions.cs
@@ -2,11 +2,14 @@
{
public class RequestOptions : IRequestOptions
{
- public RequestOptions(uint retryAttempts = BaseSpaceClientSettings.DEFAULT_RETRY_ATTEMPTS)
+ public RequestOptions(uint retryAttempts = BaseSpaceClientSettings.DEFAULT_RETRY_ATTEMPTS,
+ double powerbase = BaseSpaceClientSettings.DEFAULT_RETRY_POWER_BASE)
{
RetryAttempts = retryAttempts;
+ RetryPowerBase = powerbase;
}
public uint RetryAttempts { get; set; }
- }
+ public double RetryPowerBase { get; set; }
+ }
}