protected ElasticsearchResponse <T> StreamToTypedResponse <T>( ElasticsearchResponse <Stream> streamResponse, ITransportRequestState requestState, byte[] readBytes ) { //set response if (typeof(T) == typeof(string) || typeof(T) == typeof(byte[])) { var clone = ElasticsearchResponse.CloneFrom <T>(streamResponse, default(T)); this.SetStringOrByteResult(clone, readBytes); return(clone); } var typedResponse = ElasticsearchResponse.CloneFrom <T>(streamResponse, default(T)); using (streamResponse.Response) { var deserializationState = requestState.ResponseCreationOverride; var customConverter = deserializationState as Func <IElasticsearchResponse, Stream, T>; if (customConverter != null) { var t = customConverter(typedResponse, streamResponse.Response); typedResponse.Response = t; return(typedResponse); } var deserialized = this._serializer.Deserialize <T>(streamResponse.Response); typedResponse.Response = deserialized; return(typedResponse); } }
protected OrientdbResponse <T> StreamToTypedResponse <T>( OrientdbResponse <Stream> streamResponse, ITransportRequestState requestState, byte[] readBytes ) { //set response if (typeof(T) == typeof(string) || typeof(T) == typeof(byte[])) { OrientdbResponse <T> clone = OrientdbResponse.CloneFrom(streamResponse, default(T)); SetStringOrByteResult(clone, readBytes); return(clone); } OrientdbResponse <T> typedResponse = OrientdbResponse.CloneFrom(streamResponse, default(T)); using (streamResponse.Response) { Func <IOrientdbResponse, Stream, object> deserializationState = requestState.ResponseCreationOverride; var customConverter = deserializationState as Func <IOrientdbResponse, Stream, T>; if (customConverter != null) { T t = customConverter(typedResponse, streamResponse.Response); typedResponse.Response = t; return(typedResponse); } var deserialized = _serializer.Deserialize <T>(streamResponse.Response); typedResponse.Response = deserialized; return(typedResponse); } }
private ElasticsearchResponse <T> _deserializeToResponse <T>( ElasticsearchResponse <T> typedResponse, Stream responseStream, ITransportRequestState requestState ) { if (!IsValidResponse(requestState, typedResponse)) { return(typedResponse); } var deserializationState = requestState.ResponseCreationOverride; var customConverter = deserializationState as Func <IElasticsearchResponse, Stream, T>; if (customConverter != null) { using (responseStream) { var t = customConverter(typedResponse, responseStream); typedResponse.Response = t; return(typedResponse); } } var deserialized = this.Serializer.Deserialize <T>(responseStream); typedResponse.Response = deserialized; return(typedResponse); }
private Task <ReadResponse <T> > DeserializeAsyncToResponse <T>( Stream response, ITransportRequestState requestState, ElasticsearchResponse <T> typedResponse, ReadResponse <T> readResponse) { var tcs = new TaskCompletionSource <ReadResponse <T> >(); var responseInstantiater = requestState.ResponseCreationOverride; var customConverter = responseInstantiater as Func <IElasticsearchResponse, Stream, T>; if (customConverter == null) { return(this._serializer.DeserializeAsync <T>(response) .ContinueWith(t => { typedResponse.Response = t.Result; readResponse.Response = typedResponse; return readResponse; })); } using (response) { var t = customConverter(typedResponse, response); typedResponse.Response = t; readResponse.Response = typedResponse; tcs.SetResult(readResponse); return(tcs.Task); } }
protected void OptionallyCloseResponseStreamAndSetSuccess <T>( ITransportRequestState requestState, OrientdbServerError error, OrientdbResponse <T> typedResponse, OrientdbResponse <Stream> streamResponse) { if (streamResponse.Response != null && !typeof(Stream).IsAssignableFrom(typeof(T))) { streamResponse.Response.Close(); } if (error != null) { typedResponse.Success = false; if (typedResponse.OriginalException == null) { typedResponse.OriginalException = new OrientdbServerException(error); } } //TODO UNIT TEST OR BEGONE if (!typedResponse.Success && requestState.RequestConfiguration != null && requestState.RequestConfiguration.AllowedStatusCodes.HasAny(i => i == streamResponse.HttpStatusCode)) { typedResponse.Success = true; } }
private Task <ElasticsearchResponse <T> > StreamToTypedResponseAsync <T>( ElasticsearchResponse <Stream> streamResponse, ITransportRequestState requestState ) { var tcs = new TaskCompletionSource <ElasticsearchResponse <T> >(); //if the user explicitly wants a stream return the undisposed stream if (typeof(Stream).IsAssignableFrom(typeof(T))) { tcs.SetResult(streamResponse as ElasticsearchResponse <T>); return(tcs.Task); } var cs = ElasticsearchResponse.CloneFrom <T>(streamResponse, default(T)); if (typeof(T) == typeof(VoidResponse)) { tcs.SetResult(cs); if (streamResponse.Response != null) { streamResponse.Response.Dispose(); } return(tcs.Task); } if (!(this.Settings.KeepRawResponse || this.TypeOfResponseCopiesDirectly <T>())) { return(_deserializeAsyncToResponse(streamResponse.Response, requestState, cs)); } var memoryStream = new MemoryStream(); return(this.Iterate(this.ReadStreamAsync(streamResponse.Response, memoryStream), memoryStream) .ContinueWith(t => { var readStream = t.Result; readStream.Position = 0; var bytes = readStream.ToArray(); cs.ResponseRaw = this.Settings.KeepRawResponse ? bytes : null; var type = typeof(T); if (type == typeof(string)) { this.SetStringResult(cs as ElasticsearchResponse <string>, bytes); tcs.SetResult(cs); return tcs.Task; } if (type == typeof(byte[])) { this.SetByteResult(cs as ElasticsearchResponse <byte[]>, bytes); tcs.SetResult(cs); return tcs.Task; } return _deserializeAsyncToResponse(readStream, requestState, cs); }) .Unwrap()); }
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)); } }
private static bool IsValidResponse(ITransportRequestState requestState, IElasticsearchResponse streamResponse) { return(streamResponse.Success || (!streamResponse.Success && requestState.RequestConfiguration != null && requestState.RequestConfiguration.AllowedStatusCodes.HasAny(i => i == streamResponse.HttpStatusCode) )); }
bool ITransportDelegator.SniffOnFaultDiscoveredMoreNodes(ITransportRequestState requestState, int retried, ElasticsearchResponse <Stream> streamResponse) { if (retried != 0 || streamResponse.SuccessOrKnownError) { return(false); } Self.SniffOnConnectionFailure(requestState); return(Self.GetMaximumRetries(requestState.RequestConfiguration) > 0); }
bool ITransportDelegator.SniffOnFaultDiscoveredMoreNodes(ITransportRequestState requestState, int retried, OrientdbResponse <Stream> streamResponse) { if (!requestState.UsingPooling || retried != 0 || (streamResponse != null && streamResponse.SuccessOrKnownError)) { return(false); } Self.SniffOnConnectionFailure(requestState); return(Self.GetMaximumRetries(requestState.RequestConfiguration) > 0); }
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)); } }
Task <bool> ITransportDelegator.PingAsync(ITransportRequestState requestState) { var pingTimeout = this.Settings.PingTimeout.GetValueOrDefault(DefaultPingTimeout); pingTimeout = requestState.RequestConfiguration != null ? requestState.RequestConfiguration.ConnectTimeout.GetValueOrDefault(pingTimeout) : pingTimeout; var requestOverrides = new RequestConfiguration { ConnectTimeout = pingTimeout, RequestTimeout = pingTimeout }; var rq = requestState.InitiateRequest(RequestType.Ping); try { return(this.Connection.Head(requestState.CreatePathOnCurrentNode(""), requestOverrides) .ContinueWith(t => { if (t.IsFaulted) { rq.Finish(false, null); rq.Dispose(); throw new PingException(requestState.CurrentNode, t.Exception); } rq.Finish(t.Result.Success, t.Result.HttpStatusCode); rq.Dispose(); var response = t.Result; if (!response.HttpStatusCode.HasValue || response.HttpStatusCode.Value == -1) { throw new PingException(requestState.CurrentNode, t.Exception); } if (response.HttpStatusCode == (int)HttpStatusCode.Unauthorized) { throw new ElasticsearchAuthenticationException(response); } using (response.Response) return response.Success; })); } catch (ElasticsearchAuthenticationException) { throw; } catch (Exception e) { var tcs = new TaskCompletionSource <bool>(); var pingException = new PingException(requestState.CurrentNode, e); tcs.SetException(pingException); return(tcs.Task); } }
void ITransportDelegator.SniffOnConnectionFailure(ITransportRequestState requestState) { if (requestState.SniffedOnConnectionFailure || Self.SniffingDisabled(requestState.RequestConfiguration) || !this.ConfigurationValues.SniffsOnConnectionFault || requestState.Retried != 0) { return; } Self.SniffClusterState(requestState); requestState.SniffedOnConnectionFailure = true; }
/* REQUEST STATE *** ********************************************/ /// <summary> /// Returns whether the current delegation over nodes took too long and we should quit. /// if <see cref="ConnectionSettings.SetMaxRetryTimeout"/> is set we'll use that timeout otherwise we default to th value of /// <see cref="ConnectionSettings.SetTimeout"/> which itself defaults to 60 seconds /// </summary> bool ITransportDelegator.TookTooLongToRetry(ITransportRequestState requestState) { var timeout = this.Settings.MaxRetryTimeout.GetValueOrDefault(TimeSpan.FromMilliseconds(this.Settings.Timeout)); var startedOn = requestState.StartedOn; var now = this._dateTimeProvider.Now(); //we apply a soft margin so that if a request timesout at 59 seconds when the maximum is 60 //we also abort. var margin = (timeout.TotalMilliseconds / 100.0) * 98; var marginTimeSpan = TimeSpan.FromMilliseconds(margin); var timespanCall = (now - startedOn); var tookToLong = timespanCall >= marginTimeSpan; return(tookToLong); }
private ElasticsearchResponse <T> StreamToTypedResponse <T>( ElasticsearchResponse <Stream> streamResponse, ITransportRequestState requestState ) { //if the user explicitly wants a stream returned the undisposed stream if (typeof(Stream).IsAssignableFrom(typeof(T))) { return(streamResponse as ElasticsearchResponse <T>); } var cs = ElasticsearchResponse.CloneFrom <T>(streamResponse, default(T)); using (streamResponse.Response) using (var memoryStream = new MemoryStream()) { if (typeof(T) == typeof(VoidResponse)) { return(cs); } var type = typeof(T); if (!(this.Settings.KeepRawResponse || this.TypeOfResponseCopiesDirectly <T>())) { return(this._deserializeToResponse(cs, streamResponse.Response, requestState)); } if (streamResponse.Response != null) { streamResponse.Response.CopyTo(memoryStream); } memoryStream.Position = 0; var bytes = memoryStream.ToArray(); cs.ResponseRaw = this.Settings.KeepRawResponse ? bytes : null; if (type == typeof(string)) { this.SetStringResult(cs as ElasticsearchResponse <string>, bytes); return(cs); } if (type == typeof(byte[])) { this.SetByteResult(cs as ElasticsearchResponse <byte[]>, bytes); return(cs); } return(this._deserializeToResponse(cs, memoryStream, requestState)); } }
void ITransportDelegator.SniffOnStaleClusterState(ITransportRequestState requestState) { if (Self.SniffingDisabled(requestState.RequestConfiguration)) { return; } var sniffLifeSpan = this.ConfigurationValues.SniffInformationLifeSpan; var now = this._dateTimeProvider.Now(); if (requestState.Retried == 0 && this._lastSniff.HasValue && sniffLifeSpan.HasValue && sniffLifeSpan.Value < (now - this._lastSniff.Value)) { Self.SniffClusterState(requestState); } }
private void SniffIfInformationIsTooOld(ITransportRequestState requestState) { if (SniffingDisabled(requestState.RequestConfiguration)) { return; } var sniffLifeSpan = this.ConfigurationValues.SniffInformationLifeSpan; var now = this._dateTimeProvider.Now(); if (requestState.Retried == 0 && this._lastSniff.HasValue && sniffLifeSpan.HasValue && sniffLifeSpan.Value < (now - this._lastSniff.Value)) { this.SniffClusterState(requestState); } }
/* PING/SNIFF *** ********************************************/ bool ITransportDelegator.Ping(ITransportRequestState requestState) { var pingTimeout = this.Settings.PingTimeout.GetValueOrDefault(DefaultPingTimeout); pingTimeout = requestState.RequestConfiguration != null ? requestState.RequestConfiguration.ConnectTimeout.GetValueOrDefault(pingTimeout) : pingTimeout; var requestOverrides = new RequestConfiguration { ConnectTimeout = pingTimeout, RequestTimeout = pingTimeout }; try { ElasticsearchResponse <Stream> response; using (var rq = requestState.InitiateRequest(RequestType.Ping)) { response = this.Connection.HeadSync(requestState.CreatePathOnCurrentNode(""), requestOverrides); rq.Finish(response.Success, response.HttpStatusCode); } if (!response.HttpStatusCode.HasValue || response.HttpStatusCode.Value == -1) { throw new Exception("ping returned no status code", response.OriginalException); } if (response.HttpStatusCode == (int)HttpStatusCode.Unauthorized) { throw new ElasticsearchAuthenticationException(response); } if (response.Response == null) { return(response.Success); } using (response.Response) return(response.Success); } catch (ElasticsearchAuthenticationException) { throw; } catch (Exception e) { throw new PingException(requestState.CurrentNode, e); } }
void ITransportDelegator.SniffClusterState(ITransportRequestState requestState = null) { if (!this._connectionPool.AcceptsUpdates) { return; } var newClusterState = Self.Sniff(requestState); if (!newClusterState.HasAny()) { return; } this._connectionPool.UpdateNodeList(newClusterState); this._lastSniff = this._dateTimeProvider.Now(); }
/// <summary> /// Selects next node uri on request state /// </summary> /// <returns>bool hint whether the new current node needs to pinged first</returns> bool ITransportDelegator.SelectNextNode(ITransportRequestState requestState) { if (requestState.RequestConfiguration != null && requestState.RequestConfiguration.ForceNode != null) { requestState.Seed = 0; return(false); } int initialSeed; bool shouldPingHint; var baseUri = this._connectionPool.GetNext(requestState.Seed, out initialSeed, out shouldPingHint); requestState.Seed = initialSeed; requestState.CurrentNode = baseUri; return(shouldPingHint && !this.ConfigurationValues.DisablePings && (requestState.RequestConfiguration == null || !requestState.RequestConfiguration.DisablePing.GetValueOrDefault(false))); }
private void SetErrorDiagnosticsAndPatchSuccess <T>( ITransportRequestState requestState, ElasticsearchServerError error, ElasticsearchResponse <T> typedResponse, IElasticsearchResponse streamResponse) { if (error != null) { typedResponse.Success = false; typedResponse.OriginalException = new ElasticsearchServerException(error); } if (!typedResponse.Success && requestState.RequestConfiguration != null && requestState.RequestConfiguration.AllowedStatusCodes.HasAny(i => i == streamResponse.HttpStatusCode)) { typedResponse.Success = true; } }
protected static bool IsValidResponse(ITransportRequestState requestState, IOrientdbResponse streamResponse) { return(streamResponse.Success || StatusCodeAllowed(requestState.RequestConfiguration, streamResponse.HttpStatusCode)); }