private async Task <bool> TryHandleSpecialEndpoints(HttpListenerContext context) { try { foreach (var customEndpoint in CustomEndpoints) { if (await customEndpoint.TryHandle(context, (data, status, type) => TryWriteResponse(context, data, status, type))) { if (RequestTimings.Current.Request.ElapsedMS != null) { _metaEndpointsRoundtripTime.Record((long)RequestTimings.Current.Request.ElapsedMS, TimeUnit.Milliseconds); } return(true); } } } catch (Exception e) { var ex = GetRelevantException(e); await TryWriteResponse(context, ExceptionSerializer.Serialize(ex), GetExceptionStatusCode(ex)); return(true); } return(false); }
void ProcessIncomingRequest(ArraySegment <byte> data) { _receivedMessagesMeter.Mark(); Message msg; if (MessageSerializer.TryDeserialize(data, out msg)) { Logger.NetChannelHasReceivedMessage(Node, this, msg); var operationHeader = msg.GetHeader <OperationHeader>(); if (operationHeader != null && operationHeader.Type == OperationType.Reply) { PendingOperation continuation; if (PendingOperationsByRequestId.TryRemove(operationHeader.RequestId, out continuation)) { continuation.Expiration.Cancel(); if (!continuation.TCS.Task.IsCompleted) { var durationMs = (DateTime.Now - continuation.StartTime).TotalMilliseconds; _requestDurationTimer.Record(durationMs, TimeUnit.Milliseconds); Logger.NetChannelRequestCompleted(Node, this, msg, operationHeader.RequestId, durationMs); var invMsg = msg as ErrorMessage; if (invMsg != null) { _requestsFailedMeter.Mark(); Logger.NetChannelRequestFailed(Node, this, invMsg, operationHeader.RequestId, durationMs); continuation.TCS.SetException(new ProcessingException(invMsg.ErrorCode, invMsg.ErrorString)); } else { continuation.TCS.SetResult(msg); } } } else { OnIncomingMessage(msg); } } else { OnIncomingMessage(msg); } } }
public void Record(long time, string userValue = null) { timer.Record(time, Metrics_Net.TimeUnit.Milliseconds, userValue); }
private async Task HandleRequest(HttpListenerContext context, long ticks, long timeFromLastReq) { try { var deltaDelayTicks = DateTime.UtcNow.Ticks - ticks; var sw = Stopwatch.StartNew(); RequestTimings.ClearCurrentTimings(); using (context.Response) { // Special endpoints should not be logged/measured/traced like regular endpoints // Access is allowed without HTTPS verifications since they don't expose anything sensitive (e.g. config values are encrypted) if (await TryHandleSpecialEndpoints(context)) { return; } // Regular endpoint handling using (_activeRequestsCounter.NewContext("Request")) { RequestTimings.GetOrCreate(); // initialize request timing context string methodName = null; // Initialize with empty object for protocol backwards-compatibility. var requestData = new HttpServiceRequest { TracingData = new TracingData() }; object[] argumentsWithDefaults = null; ServiceMethod serviceMethod = null; ServiceCallEvent callEvent = _serverRequestPublisher.GetNewCallEvent(); try { try { await CheckSecureConnection(context); ValidateRequest(context); requestData = await ParseRequest(context); //----------------------------------------------------------------------------------------- // Don't move TracingContext writes main flow, IT have to be here, to avoid side changes //----------------------------------------------------------------------------------------- TracingContext.SetRequestID(requestData.TracingData.RequestID); TracingContext.SpanStartTime = requestData.TracingData.SpanStartTime; TracingContext.AbandonRequestBy = requestData.TracingData.AbandonRequestBy; TracingContext.SetParentSpan( requestData.TracingData.SpanID ?? Guid.NewGuid().ToString("N")); TracingContext.SetOverrides(requestData.Overrides); if (requestData.TracingData.Tags != null) { TracingContext.Tags = new ContextTags(requestData.TracingData.Tags); } TracingContext.AdditionalProperties = requestData.TracingData.AdditionalProperties; callEvent.ServiceMethodSchema = context.Request.IsSecureConnection ? "HTTPS" : "HTTP"; SetCallEventRequestData(callEvent, requestData); serviceMethod = ServiceEndPointDefinition.Resolve(requestData.Target); callEvent.CalledServiceName = serviceMethod.GrainInterfaceType.Name; methodName = serviceMethod.ServiceInterfaceMethod.Name; var arguments = requestData.Target.IsWeaklyTyped ? GetParametersByName(serviceMethod, requestData.Arguments) : requestData.Arguments.Values.Cast <object>().ToArray(); argumentsWithDefaults = GetConvertedAndDefaultArguments(serviceMethod.ServiceInterfaceMethod, arguments); if (_extendedDelayTimeLogging) { callEvent.RecvDateTicks = ticks; callEvent.ReqStartupDeltaTicks = deltaDelayTicks; callEvent.TimeFromLastReq = timeFromLastReq; var outstandingReqs = Interlocked.Read(ref OutstandingRequests); callEvent.OutstandingRequests = outstandingReqs; if (deltaDelayTicks > 10_000_000) { callEvent.CollectionCountGen0 = GC.CollectionCount(0); callEvent.CollectionCountGen1 = GC.CollectionCount(1); callEvent.CollectionCountGen2 = GC.CollectionCount(2); } } } catch (Exception e) { callEvent.Exception = e; if (e is RequestException) { throw; } throw new RequestException("Invalid request", e); } RejectRequestIfLateOrOverloaded(); var responseJson = await GetResponse(context, serviceMethod, requestData, argumentsWithDefaults); if (await TryWriteResponse(context, responseJson, serviceCallEvent: callEvent)) { callEvent.ErrCode = 0; _successCounter.Increment(); } else { _failureCounter.Increment(); } } catch (Exception e) { callEvent.Exception = callEvent.Exception ?? e; _failureCounter.Increment(); Exception ex = GetRelevantException(e); string json = _serializationTime.Time(() => ExceptionSerializer.Serialize(ex)); await TryWriteResponse(context, json, GetExceptionStatusCode(ex), serviceCallEvent : callEvent); } finally { sw.Stop(); callEvent.ActualTotalTime = sw.Elapsed.TotalMilliseconds; _roundtripTime.Record((long)(sw.Elapsed.TotalMilliseconds * 1000000), TimeUnit.Nanoseconds); if (methodName != null) { _endpointContext.Timer(methodName, Unit.Requests) .Record((long)(sw.Elapsed.TotalMilliseconds * 1000000), TimeUnit.Nanoseconds); } _serverRequestPublisher.TryPublish(callEvent, argumentsWithDefaults, serviceMethod); } } } } finally { Interlocked.Decrement(ref OutstandingRequests); } }