Skip to content

Commit f879228

Browse files
committed
Merge pull request #44 from cp2boston/RCB-379_csharp_429s
Added retry for 429s
2 parents b846ac0 + a772cf0 commit f879228

7 files changed

Lines changed: 80 additions & 256 deletions

File tree

docker/compile-and-run.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ function runExample() {
5555
if [[ ${result} == *"Exception"* ]]; then
5656
retcode=1
5757
fi
58-
echo ${result}
58+
echo "${result}"
5959
echo "---------- ${1} end -------------"
6060
}
6161
#------------------ Functions End ------------------------------------------------

rosette_api.sln

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
1-
2-
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio 2013
4-
VisualStudioVersion = 12.0.40629.0
5-
MinimumVisualStudioVersion = 10.0.40219.1
6-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "rosette_api", "rosette_api\rosette_api.csproj", "{D719A8A7-C5C7-49CF-BFFC-523D605E5E37}"
7-
EndProject
8-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "rosette_apiUnitTests", "rosette_apiUnitTests\rosette_apiUnitTests.csproj", "{10EAD22C-041F-4436-A391-935897309C23}"
9-
EndProject
10-
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{F17AACDD-48B8-43EA-BF0C-0129592B2BC9}"
11-
ProjectSection(SolutionItems) = preProject
12-
.nuget\packages.config = .nuget\packages.config
13-
EndProjectSection
14-
EndProject
15-
Global
16-
GlobalSection(SolutionConfigurationPlatforms) = preSolution
17-
Debug|Any CPU = Debug|Any CPU
18-
Release|Any CPU = Release|Any CPU
19-
EndGlobalSection
20-
GlobalSection(ProjectConfigurationPlatforms) = postSolution
21-
{D719A8A7-C5C7-49CF-BFFC-523D605E5E37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22-
{D719A8A7-C5C7-49CF-BFFC-523D605E5E37}.Debug|Any CPU.Build.0 = Debug|Any CPU
23-
{D719A8A7-C5C7-49CF-BFFC-523D605E5E37}.Release|Any CPU.ActiveCfg = Release|Any CPU
24-
{D719A8A7-C5C7-49CF-BFFC-523D605E5E37}.Release|Any CPU.Build.0 = Release|Any CPU
25-
{10EAD22C-041F-4436-A391-935897309C23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26-
{10EAD22C-041F-4436-A391-935897309C23}.Debug|Any CPU.Build.0 = Debug|Any CPU
27-
{10EAD22C-041F-4436-A391-935897309C23}.Release|Any CPU.ActiveCfg = Release|Any CPU
28-
{10EAD22C-041F-4436-A391-935897309C23}.Release|Any CPU.Build.0 = Release|Any CPU
29-
EndGlobalSection
30-
GlobalSection(SolutionProperties) = preSolution
31-
HideSolutionNode = FALSE
32-
EndGlobalSection
33-
EndGlobal
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 2013
4+
VisualStudioVersion = 12.0.40629.0
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "rosette_api", "rosette_api\rosette_api.csproj", "{D719A8A7-C5C7-49CF-BFFC-523D605E5E37}"
7+
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "rosette_apiUnitTests", "rosette_apiUnitTests\rosette_apiUnitTests.csproj", "{10EAD22C-041F-4436-A391-935897309C23}"
9+
EndProject
10+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{F17AACDD-48B8-43EA-BF0C-0129592B2BC9}"
11+
ProjectSection(SolutionItems) = preProject
12+
.nuget\packages.config = .nuget\packages.config
13+
EndProjectSection
14+
EndProject
15+
Global
16+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
17+
Debug|Any CPU = Debug|Any CPU
18+
Release|Any CPU = Release|Any CPU
19+
EndGlobalSection
20+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
21+
{D719A8A7-C5C7-49CF-BFFC-523D605E5E37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22+
{D719A8A7-C5C7-49CF-BFFC-523D605E5E37}.Debug|Any CPU.Build.0 = Debug|Any CPU
23+
{D719A8A7-C5C7-49CF-BFFC-523D605E5E37}.Release|Any CPU.ActiveCfg = Release|Any CPU
24+
{D719A8A7-C5C7-49CF-BFFC-523D605E5E37}.Release|Any CPU.Build.0 = Release|Any CPU
25+
{10EAD22C-041F-4436-A391-935897309C23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26+
{10EAD22C-041F-4436-A391-935897309C23}.Debug|Any CPU.Build.0 = Debug|Any CPU
27+
{10EAD22C-041F-4436-A391-935897309C23}.Release|Any CPU.ActiveCfg = Release|Any CPU
28+
{10EAD22C-041F-4436-A391-935897309C23}.Release|Any CPU.Build.0 = Release|Any CPU
29+
EndGlobalSection
30+
GlobalSection(SolutionProperties) = preSolution
31+
HideSolutionNode = FALSE
32+
EndGlobalSection
33+
EndGlobal

rosette_api/CAPI.cs

Lines changed: 38 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,11 @@ public class CAPI {
7070
/// <param name="uristring">(string, optional): Base URL for the HttpClient requests. If none is given, will use the default API URI</param>
7171
/// <param name="maxRetry">(int, optional): Maximum number of times to retry a request on HttpResponse error. Default is 3 times.</param>
7272
/// <param name="client">(HttpClient, optional): Forces the API to use a custom HttpClient.</param>
73-
public CAPI(string user_key, string uristring = "https://api.rosette.com/rest/v1/", int maxRetry = 1, HttpClient client = null) {
73+
public CAPI(string user_key, string uristring = "https://api.rosette.com/rest/v1/", int maxRetry = 5, HttpClient client = null) {
7474
UserKey = user_key;
7575
URIstring = (uristring == null) ? "https://api.rosette.com/rest/v1/" : uristring;
7676
MaxRetry = (maxRetry == 0) ? 1 : maxRetry;
77+
MillisecondsBetweenRetries = 500000;
7778
Debug = false;
7879
Timeout = 300;
7980
Client = client;
@@ -125,6 +126,14 @@ private set {
125126
/// </summary>
126127
public int MaxRetry { get; set; }
127128

129+
/// <summary>MillisecondsBetweenRetries
130+
/// <para>
131+
/// Getter, Setter for the MillisecondsBetweenRetries
132+
/// MillisecondsBetweenRetries: milliseconds between retry attempts
133+
/// </para>
134+
/// </summary>
135+
public int MillisecondsBetweenRetries { get; set; }
136+
128137
/// <summary>Client
129138
/// <para>
130139
/// Getter, Setter for the Client
@@ -762,24 +771,30 @@ private RosetteResponse getResponse(HttpClient client, string jsonRequest = null
762771
wholeURI = wholeURI.Substring(1);
763772
}
764773

765-
if (jsonRequest != null) {
766-
HttpContent content = new StringContent(jsonRequest);
767-
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
768-
Task<HttpResponseMessage> task = Task.Run<HttpResponseMessage>(async () => await client.PostAsync(wholeURI, content));
769-
responseMsg = task.Result;
770-
}
771-
else if (multiPart != null) {
772-
Task<HttpResponseMessage> task = Task.Run<HttpResponseMessage>(async () => await client.PostAsync(wholeURI, multiPart));
773-
responseMsg = task.Result;
774-
}
775-
else {
776-
Task<HttpResponseMessage> task = Task.Run<HttpResponseMessage>(async () => await client.GetAsync(wholeURI));
777-
responseMsg = task.Result;
778-
}
774+
for (int attempt = 0; attempt < MaxRetry; attempt++) {
775+
if (jsonRequest != null) {
776+
HttpContent content = new StringContent(jsonRequest);
777+
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
778+
Task<HttpResponseMessage> task = Task.Run<HttpResponseMessage>(async () => await client.PostAsync(wholeURI, content));
779+
responseMsg = task.Result;
780+
}
781+
else if (multiPart != null) {
782+
Task<HttpResponseMessage> task = Task.Run<HttpResponseMessage>(async () => await client.PostAsync(wholeURI, multiPart));
783+
responseMsg = task.Result;
784+
}
785+
else {
786+
Task<HttpResponseMessage> task = Task.Run<HttpResponseMessage>(async () => await client.GetAsync(wholeURI));
787+
responseMsg = task.Result;
788+
}
789+
if ((int)responseMsg.StatusCode == 429) {
790+
System.Threading.Thread.Sleep(MillisecondsBetweenRetries);
791+
continue;
792+
}
779793

780-
RosetteResponse response = new RosetteResponse(responseMsg);
794+
RosetteResponse response = new RosetteResponse(responseMsg);
781795

782-
return response;
796+
return response;
797+
}
783798

784799
}
785800
return null;
@@ -891,69 +906,19 @@ private bool checkVersion(string versionToCheck = null) {
891906
if (versionToCheck == null) {
892907
versionToCheck = Version;
893908
}
894-
HttpClient client = SetupClient();
895-
HttpResponseMessage responseMsg = null;
896-
int retry = 0;
909+
version_checked = true;
910+
last_version_check = DateTime.Now;
911+
_uri = string.Format("info?clientVersion={0}", versionToCheck);
912+
RosetteResponse response = getResponse(SetupClient(), string.Empty);
897913

898-
while (responseMsg == null || (!responseMsg.IsSuccessStatusCode && retry <= MaxRetry)) {
899-
if (retry > 0) {
900-
System.Threading.Thread.Sleep(500);
901-
}
902-
string url = string.Format("info?clientVersion={0}", versionToCheck);
903-
HttpContent content = new StringContent(string.Empty);
904-
responseMsg = client.PostAsync(url, content).Result;
905-
retry = retry + 1;
906-
}
907-
string text = "";
908-
try {
909-
text = getMessage(responseMsg)[0];
910-
}
911-
catch (RosetteException) {
912-
throw;
913-
}
914-
var result = new JavaScriptSerializer().Deserialize<dynamic>(text);
915-
// compatibility with server side is at minor version level of semver
916-
if (!result["versionChecked"]) {
914+
if (!response.Content.ContainsKey("versionChecked") || response.Content["versionChecked"].ToString() != "True") {
915+
version_checked = false;
917916
throw new RosetteException("The server version is not compatible with binding version " + versionToCheck, -6);
918917
}
919-
else {
920-
version_checked = true;
921-
last_version_check = DateTime.Now;
922-
}
923918
}
924919
return version_checked;
925920
}
926921

927-
/// <summary>getMessage
928-
/// <para>Helper function to parse out responseMsg based on gzip or not</para>
929-
/// </summary>
930-
/// <param name="responseMsg">(HttpResponseMessage): Response Message sent from the server</param>
931-
/// <returns>(string): Content of the response message</returns>
932-
private List<string> getMessage(HttpResponseMessage responseMsg) {
933-
if (responseMsg.IsSuccessStatusCode) {
934-
byte[] byteArray = responseMsg.Content.ReadAsByteArrayAsync().Result;
935-
IEnumerator<KeyValuePair<string, IEnumerable<string>>> responseHeadersEnum = responseMsg.Headers.GetEnumerator();
936-
Dictionary<string, string> responseHeadersDict = new Dictionary<string, string>();
937-
while (responseHeadersEnum.MoveNext()) {
938-
KeyValuePair<string, IEnumerable<string>> pair = responseHeadersEnum.Current;
939-
responseHeadersDict.Add(pair.Key, pair.Value.ToArray()[0]);
940-
}
941-
942-
if (responseMsg.Content.Headers.ContentEncoding.Contains("gzip") || (byteArray[0] == '\x1f' && byteArray[1] == '\x8b' && byteArray[2] == '\x08')) {
943-
byteArray = Decompress(byteArray);
944-
}
945-
MemoryStream stream = new MemoryStream(byteArray);
946-
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
947-
List<string> message = new List<string>();
948-
message.Add(reader.ReadToEnd());
949-
message.Add(new JavaScriptSerializer().Serialize(responseHeadersDict));
950-
return message;
951-
}
952-
else {
953-
throw new RosetteException(responseMsg.ReasonPhrase, (int)responseMsg.StatusCode);
954-
}
955-
}
956-
957922
/// <summary>Decompress
958923
/// <para>Method to decompress GZIP files
959924
/// Source: http://www.dotnetperls.com/decompress

rosette_api/RosetteResponse.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ public RosetteResponse(HttpResponseMessage responseMsg) {
5757
}
5858
}
5959

60+
private string headersAsString() {
61+
StringBuilder itemString = new StringBuilder();
62+
foreach (var item in Headers)
63+
itemString.AppendFormat("-- {0}:{1} -- ", item.Key, item.Value);
64+
65+
return itemString.ToString();
66+
}
67+
6068

6169
/// <summary>Decompress
6270
/// <para>Method to decompress GZIP files

rosette_apiExamples/rosette_apiExamples.csproj

Lines changed: 0 additions & 115 deletions
This file was deleted.

rosette_apiExamples/rosette_apiExamples.sln

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)