Revision 7d915c34 trunk/Pithos.Network/PithosClient.cs

b/trunk/Pithos.Network/PithosClient.cs
7 7
using System.Collections.Specialized;
8 8
using System.Diagnostics;
9 9
using System.Diagnostics.Contracts;
10
using System.IO;
10 11
using System.Net;
11 12
using System.Runtime.Serialization;
13
using System.Threading.Tasks;
12 14

  
13 15
namespace Pithos.Network
14 16
{
......
84 86

  
85 87
        protected override WebResponse GetWebResponse(WebRequest request)
86 88
        {
89
            try
90
            {
91

  
87 92
            var response = (HttpWebResponse)base.GetWebResponse(request);
88 93
            StatusCode = response.StatusCode;
89 94
            StatusDescription = response.StatusDescription;
90 95
            return response;
96
            }
97
            catch (WebException exc)
98
            {
99
                if (exc.Response.ContentLength > 0)
100
                {
101
                    string content;
102
                    content = GetContent(exc.Response);
103
                    Trace.TraceError(content);
104
                }
105
                throw;
106
            }
107
        }
108

  
109
        private static string GetContent(WebResponse webResponse)
110
        {
111
            string content;
112
            using (var stream = webResponse.GetResponseStream())
113
            using (var reader = new StreamReader(stream))
114
            {
115
                content = reader.ReadToEnd();
116
            }
117
            return content;
91 118
        }
92 119

  
93 120
        public string DownloadStringWithRetry(string address,int retries=0)
......
100 127
            var actualRetries = (retries == 0) ? Retries : retries;
101 128
            
102 129

  
103
            var func = Retry(() =>
130
            
131
            var task = Retry(() =>
104 132
            {
105 133
                var uriString = String.Join("/", BaseAddress, actualAddress);
106 134
                var content = base.DownloadString(uriString);
......
111 139

  
112 140
            }, actualRetries);
113 141

  
114
            var result = func();
142
            var result = task.Result;
115 143
            return result;
116 144
        }
117 145

  
......
147 175
            var actualAddress = GetActualAddress(address);
148 176

  
149 177
            var actualRetries = (retries == 0) ? Retries : retries;
150
            var func = Retry(() =>
178
            var task = Retry(() =>
151 179
            {
152 180
                var uriString = String.Join("/",BaseAddress ,actualAddress);
153 181
                var uri = new Uri(uriString);
......
164 192
                return 0;
165 193
            }, actualRetries);
166 194

  
167
            func();
195
            task.Wait();
168 196
        }
169 197

  
170 198
        private string GetActualAddress(string address)
......
191 219
                throw new ArgumentNullException("address");
192 220

  
193 221
            var actualRetries = (retries == 0) ? Retries : retries;            
194
            var func = Retry(() =>
222
            var task = Retry(() =>
195 223
            {
196 224
                var content = base.DownloadString(address);
197 225

  
......
201 229

  
202 230
            }, actualRetries);
203 231

  
204
            var result = func();
232
            var result = task.Result;
205 233
            return result;
206 234
        }
207 235

  
......
243 271
                throw new WebException(String.Format("{0} with code {1} - {2}", message, StatusCode, StatusDescription));
244 272
        }
245 273

  
246
        private Func<T> Retry<T>(Func< T> original, int retryCount)
274
        /*private Func<T> Retry<T>(Func< T> original, int retryCount)
247 275
        {
248 276
            return () =>
249 277
            {
......
305 333
                    }
306 334
                }
307 335
            };
336
        }*/
337
        
338
        private Task<T> Retry<T>(Func< T> original, int retryCount)
339
        {
340
            return Task.Factory.StartNew(() => original()).ContinueWith(_original =>
341
                {
342
                    if(_original.IsFaulted )
343
                    {
344
                        var e = _original.Exception.InnerException;
345
                        if (e is WebException)
346
                        {
347
                            var we = (e as WebException);
348
                            var statusCode = ((HttpWebResponse) we.Response).StatusCode;
349
                            this.StatusCode = statusCode;
350

  
351
                            if (we.Status==WebExceptionStatus.Timeout || 
352
                                (we.Status==WebExceptionStatus.ProtocolError && statusCode==HttpStatusCode.ServiceUnavailable))
353
                            {
354
                                TimedOut = true;
355
                                if (retryCount == 0)
356
                                {
357
                                    Trace.TraceError("[ERROR] Timed out too many times. {0}\n", e);
358
                                    throw new RetryException("Timed out too many times.", e);
359
                                }
360
                                Trace.TraceError(
361
                                    "[RETRY] Timed out after {0} ms. Will retry {1} more times\n{2}", Timeout,
362
                                    retryCount, e);
363
                                return Retry(original, retryCount - 1);
364
                            }
365

  
366
                            if (statusCode==HttpStatusCode.NotFound)
367
                                return new Task<T>(() => default(T));                            
368
                        }
369
                        throw e;
370
                    }
371
                    else                    
372
                        return Task<T>.Factory.StartNew(() => _original.Result);
373
                }).Unwrap();
308 374
        }
309 375

  
310 376
       

Also available in: Unified diff