/* ASYNC *** ********************************************/ public Task <ElasticsearchResponse <T> > DoRequestAsync <T>(string method, string path, object data = null, IRequestParameters requestParameters = null) { using (var requestState = new TransportRequestState <T>(this.Settings, requestParameters, method, path)) { var bytes = PostData(data); requestState.TickSerialization(bytes); return(this.DoRequestAsync <T>(requestState) .ContinueWith(t => { var tcs = new TaskCompletionSource <ElasticsearchResponse <T> >(); if (t.Exception != null) { tcs.SetException(t.Exception.Flatten()); requestState.SetResult(null); } else { tcs.SetResult(t.Result); requestState.SetResult(t.Result); } return tcs.Task; }).Unwrap() ); } }
private Task <ElasticsearchResponse <T> > DoRequestAsync <T>(TransportRequestState <T> requestState) { this.SniffIfInformationIsTooOld(requestState); var uriRequiresPing = this.SelectNextNode(requestState); if (uriRequiresPing) { return(this.PingAsync(requestState) .ContinueWith(t => { if (t.IsFaulted) { requestState.SeenExceptions.Add(t.Exception.InnerException); return this.RetryRequestAsync(requestState); } if (t.IsCompleted) { return this.FinishOrRetryRequestAsync(requestState); } return null; }).Unwrap()); } return(FinishOrRetryRequestAsync(requestState)); }
private Task <ElasticsearchResponse <Stream> > CallIntoConnectionAsync <T>(TransportRequestState <T> requestState) { var uri = requestState.CreatePathOnCurrentNode(); var postData = requestState.PostData; var requestConfiguration = requestState.RequestConfiguration; var method = requestState.Method.ToLowerInvariant(); try { switch (method) { case "head": return(this._connection.Head(uri, requestConfiguration)); case "get": return(this._connection.Get(uri, requestConfiguration)); case "post": return(this._connection.Post(uri, postData, requestConfiguration)); case "put": return(this._connection.Put(uri, postData, requestConfiguration)); case "delete": return(postData == null || postData.Length == 0 ? this._connection.Delete(uri, requestConfiguration) : this._connection.Delete(uri, postData, requestConfiguration)); default: throw new Exception("Unknown HTTP method " + requestState.Method); } } catch (Exception e) { var tcs = new TaskCompletionSource <ElasticsearchResponse <Stream> >(); tcs.SetException(e); return(tcs.Task); } }
private ElasticsearchResponse <T> CoordinateRequest <T>(TransportRequestState <T> requestState, int maxRetries, int retried, ref bool aliveResponse) { var pingRetryRequest = this.SelectNextNode(requestState); if (pingRetryRequest != null) { return(pingRetryRequest); } var streamResponse = this.DoElasticsearchCall(requestState); aliveResponse = streamResponse.SuccessOrKnownError; if (!this.DoneProcessing(streamResponse, requestState, maxRetries, retried)) { return(null); } ElasticsearchServerError error = null; var typedResponse = this.ReturnStreamOrVoidResponse(requestState, streamResponse) ?? this.ReturnTypedResponse(requestState, streamResponse, out error); this.OptionallyCloseResponseStreamAndSetSuccess(requestState, error, typedResponse, streamResponse); if (error != null && this._settings.ThrowOnElasticsearchServerExceptions) { throw new ElasticsearchServerException(error); } return(typedResponse); }
protected void ThrowMaxRetryExceptionWhenNeeded <T>(TransportRequestState <T> requestState, int maxRetries) { bool tookToLong = _delegator.TookTooLongToRetry(requestState); //not out of date and we havent depleted our retries, get the hell out of here if (!tookToLong && requestState.Retried < maxRetries) { return; } List <Exception> innerExceptions = requestState.SeenExceptions.Where(e => e != null).ToList(); Exception innerException = !innerExceptions.HasAny() ? null : (innerExceptions.Count() == 1) ? innerExceptions.First() : new AggregateException(requestState.SeenExceptions); //When we are not using pooling we forcefully rethrow the exception //and never wrap it in a maxretry exception if (!requestState.UsingPooling && innerException != null) { throw innerException; } string exceptionMessage = tookToLong ? CreateTookTooLongExceptionMessage(requestState, innerException) : CreateMaxRetryExceptionMessage(requestState, innerException); throw new MaxRetryException(exceptionMessage, innerException); }
private OrientdbResponse <Stream> CallInToConnection <T>(TransportRequestState <T> requestState) { Uri uri = requestState.CreatePathOnCurrentNode(); byte[] postData = requestState.PostData; IRequestConfiguration requestConfiguration = requestState.RequestConfiguration; switch (requestState.Method.ToLowerInvariant()) { case "post": return(_connection.PostSync(uri, postData, requestConfiguration)); case "put": return(_connection.PutSync(uri, postData, requestConfiguration)); case "head": return(_connection.HeadSync(uri, requestConfiguration)); case "get": return(_connection.GetSync(uri, requestConfiguration)); case "delete": return(postData == null || postData.Length == 0 ? _connection.DeleteSync(uri, requestConfiguration) : _connection.DeleteSync(uri, postData, requestConfiguration)); } throw new Exception("Unknown HTTP method " + requestState.Method); }
private static string CreateMaxRetryExceptionMessage <T>(TransportRequestState <T> requestState, Exception e) { string innerException = null; if (e != null) { var aggregate = e as AggregateException; if (aggregate != null) { aggregate = aggregate.Flatten(); var innerExceptions = aggregate.InnerExceptions .Select(ae => MaxRetryInnerMessage.F(ae.GetType().Name, ae.Message, ae.StackTrace)) .ToList(); innerException = "\r\n" + string.Join("\r\n", innerExceptions); } else { innerException = "\r\n" + MaxRetryInnerMessage.F(e.GetType().Name, e.Message, e.StackTrace); } } var exceptionMessage = MaxRetryExceptionMessage .F(requestState.Method, requestState.Path, requestState.Retried, innerException); return(exceptionMessage); }
private OrientdbResponse <T> CoordinateRequest <T>(TransportRequestState <T> requestState, int maxRetries, int retried, ref bool aliveResponse) { OrientdbResponse <T> pingRetryRequest = SelectNextNode(requestState); if (pingRetryRequest != null) { return(pingRetryRequest); } OrientdbResponse <Stream> streamResponse = DoOrientdbCall(requestState); aliveResponse = streamResponse.SuccessOrKnownError; if (!DoneProcessing(streamResponse, requestState, maxRetries, retried)) { return(null); } OrientdbServerError error = null; OrientdbResponse <T> typedResponse = ReturnStreamOrVoidResponse(requestState, streamResponse) ?? ReturnTypedResponse(requestState, streamResponse, out error); OptionallyCloseResponseStreamAndSetSuccess(requestState, error, typedResponse, streamResponse); if (error != null && _settings.ThrowOnOrientdbServerExceptions) { throw new OrientdbServerException(error); } return(typedResponse); }
IList <Uri> ITransportDelegator.Sniff(ITransportRequestState ownerState = null) { int pingTimeout = Settings.PingTimeout.GetValueOrDefault(DefaultPingTimeout); var requestOverrides = new RequestConfiguration { ConnectTimeout = pingTimeout, RequestTimeout = pingTimeout, DisableSniff = true //sniff call should never recurse }; var requestParameters = new RequestParameters { RequestConfiguration = requestOverrides }; try { string path = "_nodes/_all/clear?timeout=" + pingTimeout; OrientdbResponse <Stream> response; using (var requestState = new TransportRequestState <Stream>(Settings, requestParameters, "GET", path)) { response = _requestHandler.Request(requestState); //inform the owing request state of the requests the sniffs did. if (requestState.RequestMetrics != null && ownerState != null) { foreach ( RequestMetrics r in requestState.RequestMetrics.Where(p => p.RequestType == RequestType.OrientdbCall)) { r.RequestType = RequestType.Sniff; } if (ownerState.RequestMetrics == null) { ownerState.RequestMetrics = new List <RequestMetrics>(); } ownerState.RequestMetrics.AddRange(requestState.RequestMetrics); } if (response.HttpStatusCode.HasValue && response.HttpStatusCode == (int)HttpStatusCode.Unauthorized) { throw new OrientdbAuthenticationException(response); } if (response.Response == null) { return(null); } using (response.Response) { return(Sniffer.FromStream(response, response.Response, Serializer)); } } } catch (MaxRetryException e) { throw new MaxRetryException(new SniffException(e)); } }
public Task <OrientdbResponse <T> > DoRequestAsync <T>(string method, string path, object data = null, IRequestParameters requestParameters = null) { using (var requestState = new TransportRequestState <T>(Settings, requestParameters, method, path)) { return(_requestHandlerAsync.RequestAsync(requestState, data)); } }
protected string CreateMaxRetryExceptionMessage <T>(TransportRequestState <T> requestState, Exception e) { string innerException = CreateInnerExceptionMessage(requestState, e); string exceptionMessage = MaxRetryExceptionMessage .F(requestState.Method, requestState.Path, requestState.Retried, innerException); return(exceptionMessage); }
private Task <ElasticsearchResponse <T> > FinishOrRetryRequestAsync <T>(TransportRequestState <T> requestState) { var rq = requestState.InitiateRequest(RequestType.ElasticsearchCall); return(CallIntoConnectionAsync(requestState) .ContinueWith(t => HandleStreamResponse(t, rq, requestState)) .Unwrap()); }
protected string CreateTookTooLongExceptionMessage <T>(TransportRequestState <T> requestState, Exception e) { string innerException = CreateInnerExceptionMessage(requestState, e); TimeSpan timeout = _settings.MaxRetryTimeout.GetValueOrDefault(TimeSpan.FromMilliseconds(_settings.Timeout)); string exceptionMessage = TookTooLongExceptionMessage .F(requestState.Method, requestState.Path, requestState.Retried, innerException, timeout); return(exceptionMessage); }
private ElasticsearchResponse <T> DoRequest <T>(TransportRequestState <T> requestState) { var sniffAuthResponse = this.TrySniffOnStaleClusterState(requestState); if (sniffAuthResponse != null) { return(sniffAuthResponse); } bool aliveResponse = false; bool seenError = false; int retried = requestState.Retried; int maxRetries = this._delegator.GetMaximumRetries(requestState.RequestConfiguration); try { var response = this.CoordinateRequest(requestState, maxRetries, retried, ref aliveResponse); if (response != null) { return(response); } } catch (ElasticsearchAuthenticationException e) { return(this.HandleAuthenticationException(requestState, e)); } catch (MaxRetryException) { //TODO ifdef ExceptionDispatchInfo.Capture(ex).Throw(); throw; } catch (ElasticsearchServerException) { //TODO ifdef ExceptionDispatchInfo.Capture(ex).Throw(); throw; } catch (Exception e) { requestState.SeenExceptions.Add(e); if (!requestState.UsingPooling || maxRetries == 0 && retried == 0) { //TODO ifdef ExceptionDispatchInfo.Capture(ex).Throw(); throw; } seenError = true; return(RetryRequest <T>(requestState)); } finally { //make sure we always call markalive on the uri if the connection was succesful if (!seenError && aliveResponse) { this._connectionPool.MarkAlive(requestState.CurrentNode); } } return(this.RetryRequest(requestState)); }
public OrientdbResponse <T> Request <T>(TransportRequestState <T> requestState, object data = null) { byte[] postData = PostData(data); requestState.TickSerialization(postData); OrientdbResponse <T> response = DoRequest(requestState); requestState.SetResult(response); return(response); }
protected void SetAuthenticationExceptionOnRequestState <T>( TransportRequestState <T> requestState, ElasticsearchAuthenticationException exception, TaskCompletionSource <ElasticsearchResponse <T> > tcs) { var result = this.HandleAuthenticationException(requestState, exception); tcs.SetResult(result); requestState.SetResult(result); }
public ElasticsearchResponse <T> Request <T>(TransportRequestState <T> requestState, object data = null) { var postData = PostData(data); requestState.TickSerialization(postData); var response = this.DoRequest <T>(requestState); requestState.SetResult(response); return(response); }
/// <summary> /// Determines whether the stream response is our final stream response: /// IF response is success or known error /// OR maxRetries is 0 and retried is 0 (maxRetries could change in between retries to 0) /// AND sniff on connection fault does not find more nodes (causing maxRetry to grow) /// AND maxretries is no retried /// </summary> protected bool DoneProcessing <T>( OrientdbResponse <Stream> streamResponse, TransportRequestState <T> requestState, int maxRetries, int retried) { return((streamResponse != null && streamResponse.SuccessOrKnownError) || (maxRetries == 0 && retried == 0 && !_delegator.SniffOnFaultDiscoveredMoreNodes(requestState, retried, streamResponse) )); }
private IList <Uri> Sniff(ITransportRequestState ownerState = null) { var pingTimeout = this.Settings.PingTimeout.GetValueOrDefault(50); var requestOverrides = new RequestConfiguration { ConnectTimeout = pingTimeout, RequestTimeout = pingTimeout, DisableSniff = true //sniff call should never recurse }; var requestParameters = new RequestParameters { RequestConfiguration = requestOverrides }; try { var path = "_nodes/_all/clear?timeout=" + pingTimeout; ElasticsearchResponse <Stream> response; using (var requestState = new TransportRequestState <Stream>(this.Settings, requestParameters, "GET", path)) { response = this.DoRequest(requestState); //inform the owing request state of the requests the sniffs did. if (requestState.RequestMetrics != null && ownerState != null) { foreach (var r in requestState.RequestMetrics.Where(p => p.RequestType == RequestType.ElasticsearchCall)) { r.RequestType = RequestType.Sniff; } if (ownerState.RequestMetrics == null) { ownerState.RequestMetrics = new List <RequestMetrics>(); } ownerState.RequestMetrics.AddRange(requestState.RequestMetrics); } if (response.Response == null) { return(null); } using (response.Response) { return(Sniffer.FromStream(response, response.Response, this.Serializer)); } } } catch (MaxRetryException e) { throw new MaxRetryException(new SniffException(e)); } }
/// <summary> /// Determines whether the stream response is our final stream response: /// IF response is success or known error /// OR maxRetries is 0 and retried is 0 (maxRetries could change in between retries to 0) /// AND sniff on connection fault does not find more nodes (causing maxRetry to grow) /// AND maxretries is no retried /// </summary> protected bool DoneProcessing <T>( ElasticsearchResponse <Stream> streamResponse, TransportRequestState <T> requestState, int maxRetries, int retried) { return(streamResponse.SuccessOrKnownError || (maxRetries == 0 && retried == 0 && !this._delegator.SniffOnFaultDiscoveredMoreNodes(requestState, retried, streamResponse) )); }
private Task <ElasticsearchResponse <T> > RetryRequestAsync <T>(TransportRequestState <T> requestState) { var maxRetries = this._delegator.GetMaximumRetries(requestState.RequestConfiguration); this._connectionPool.MarkDead(requestState.CurrentNode, this._settings.DeadTimeout, this._settings.MaxDeadTimeout); this._delegator.SniffOnConnectionFailure(requestState); this.ThrowMaxRetryExceptionWhenNeeded(requestState, maxRetries); return(this.DoRequestAsync <T>(requestState)); }
private ElasticsearchResponse <T> RetryRequest <T>(TransportRequestState <T> requestState) { var maxRetries = this.GetMaximumRetries(requestState.RequestConfiguration); this._connectionPool.MarkDead(requestState.CurrentNode, this.ConfigurationValues.DeadTimeout, this.ConfigurationValues.MaxDeadTimeout); SniffOnConnectionFailure(requestState); ThrowMaxRetryExceptionWhenNeeded(requestState, maxRetries); return(this.DoRequest <T>(requestState)); }
private Task <ElasticsearchResponse <T> > FinishOrRetryRequestAsync <T>(TransportRequestState <T> requestState) { var rq = requestState.InitiateRequest(RequestType.ElasticsearchCall); return(CallIntoConnectionAsync(requestState) .ContinueWith(t => { var retried = requestState.Retried; if (t.IsCanceled) { return null; } var maxRetries = this.GetMaximumRetries(requestState.RequestConfiguration); if (t.IsFaulted) { rq.Dispose(); if (maxRetries == 0 && retried == 0) { throw t.Exception; } requestState.SeenExceptions.Add(t.Exception); return this.RetryRequestAsync <T>(requestState); } if (t.Result.SuccessOrKnownError || ( maxRetries == 0 && retried == 0 && !SniffOnFaultDiscoveredMoreNodes(requestState, retried, t.Result)) ) { rq.Finish(t.Result.Success, t.Result.HttpStatusCode); rq.Dispose(); var error = ThrowOrGetErrorFromStreamResponse(requestState, t.Result); return this.StreamToTypedResponseAsync <T>(t.Result, requestState) .ContinueWith(tt => { this.SetErrorDiagnosticsAndPatchSuccess(requestState, error, tt.Result, t.Result); if (tt.Result.SuccessOrKnownError) { this._connectionPool.MarkAlive(requestState.CurrentNode); } return tt; }).Unwrap(); } if (t.Result != null) { rq.Finish(t.Result.Success, t.Result.HttpStatusCode); } rq.Dispose(); return this.RetryRequestAsync <T>(requestState); }).Unwrap()); }
public Task <ElasticsearchResponse <T> > RequestAsync <T>(TransportRequestState <T> requestState, object data = null) { // Serialize request and inform requestState so it can keep track of serialization times var bytes = PostData(data); requestState.TickSerialization(bytes); return(this.DoRequestAsync <T>(requestState) // When the request returns again inform the request state so it can do its bookkeeping .ContinueWith(t => this.SetResultOnRequestState(t, requestState)) .Unwrap()); }
private ElasticsearchResponse <Stream> DoElasticsearchCall <T>(TransportRequestState <T> requestState) { // Do the actual request by calling into IConnection // We wrap it in a IRequestTimings to audit the request ElasticsearchResponse <Stream> streamResponse; using (var requestAudit = requestState.InitiateRequest(RequestType.ElasticsearchCall)) { streamResponse = this.CallInToConnection(requestState); requestAudit.Finish(streamResponse.Success, streamResponse.HttpStatusCode); } return(streamResponse); }
private OrientdbResponse <Stream> DoOrientdbCall <T>(TransportRequestState <T> requestState) { // Do the actual request by calling into IConnection // We wrap it in a IRequestTimings to audit the request OrientdbResponse <Stream> streamResponse; using (IRequestTimings requestAudit = requestState.InitiateRequest(RequestType.OrientdbCall)) { streamResponse = CallInToConnection(requestState); requestAudit.Finish(streamResponse.Success, streamResponse.HttpStatusCode); } return(streamResponse); }
/// <summary> /// Sniffs when the cluster state is stale, when sniffing returns a 401 return a response for T to return directly /// </summary> protected OrientdbResponse <T> TrySniffOnStaleClusterState <T>(TransportRequestState <T> requestState) { try { //If connectionSettings is configured to sniff periodically, sniff when stale. _delegator.SniffOnStaleClusterState(requestState); return(null); } catch (OrientdbAuthenticationException e) { return(HandleAuthenticationException(requestState, e)); } }
/* SYNC *** ********************************************/ public ElasticsearchResponse <T> DoRequest <T>(string method, string path, object data = null, IRequestParameters requestParameters = null) { using (var requestState = new TransportRequestState <T>(this.Settings, requestParameters, method, path)) { var bytes = PostData(data); requestState.TickSerialization(bytes); var result = this.DoRequest <T>(requestState); requestState.SetResult(result); return(result); } }
protected ElasticsearchResponse <T> HandleAuthenticationException <T>(TransportRequestState <T> requestState, ElasticsearchAuthException exception) { if (requestState.ClientSettings.ThrowOnElasticsearchServerExceptions) { throw exception.ToElasticsearchServerException(); } var response = ElasticsearchResponse.CloneFrom <T>(exception.Response, default(T)); response.Request = requestState.PostData; response.RequestUrl = requestState.Path; response.RequestMethod = requestState.Method; return(response); }
private ElasticsearchResponse <T> SelectNextNode <T>(TransportRequestState <T> requestState) { // Select the next node to hit and signal whether the selected node needs a ping var nodeRequiresPinging = this._delegator.SelectNextNode(requestState); if (!nodeRequiresPinging) { return(null); } var pingSuccess = this._delegator.Ping(requestState); // If ping is not successful retry request on the next node the connection pool selects return(!pingSuccess?RetryRequest <T>(requestState) : null); }