public AfterWrappedMethodDelegate BeforeWrappedMethod(InstrumentedMethodCall instrumentedMethodCall, IAgent agent, ITransaction transaction) { if (instrumentedMethodCall.IsAsync) { transaction.AttachToAsync(); } var operation = Common.GetRedisCommand(instrumentedMethodCall.MethodCall, AssemblyName); var connectionInfo = Common.GetConnectionInfoFromConnectionMultiplexer(instrumentedMethodCall.MethodCall, AssemblyName); var segment = transaction.StartDatastoreSegment(instrumentedMethodCall.MethodCall, ParsedSqlStatement.FromOperation(DatastoreVendor.Redis, operation), connectionInfo); //We're not using Delegates.GetAsyncDelegateFor(agent, segment) because if an async redis call is made from an asp.net mvc action, //the continuation may not run until that mvc action has finished executing, or has yielded execution, because the synchronization context //will only allow one thread to execute at a time. To work around this limitation, since we don't need access to HttpContext in our continuation, //we can just provide the TaskContinuationOptions.HideScheduler flag so that we will use the default ThreadPool scheduler to schedule our //continuation. Using the ThreadPool scheduler allows our continuation to run without needing to wait for the mvc action to finish executing or //yielding its execution. We're not applying this change across the board, because we still need to better understand the impact of making this //change more broadly vs just fixing a known customer issue. return(Delegates.GetAsyncDelegateFor <Task>(agent, segment, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.HideScheduler)); }
public AfterWrappedMethodDelegate BeforeWrappedMethod(InstrumentedMethodCall instrumentedMethodCall, IAgent agent, ITransaction transaction) { var redisCommandWithArgumentsAsBytes = instrumentedMethodCall.MethodCall.MethodArguments.ExtractNotNullAs <byte[][]>(0); var redisCommand = redisCommandWithArgumentsAsBytes[0]; if (redisCommand == null) { return(Delegates.NoOp); } var operation = GetRedisCommand(redisCommand); var contextObject = instrumentedMethodCall.MethodCall.InvocationTarget; if (contextObject == null) { throw new NullReferenceException(nameof(contextObject)); } var host = TryGetPropertyName(PropertyHost, contextObject) ?? "unknown"; host = ConnectionStringParserHelper.NormalizeHostname(host); var portPathOrId = TryGetPropertyName(PropertyPortPathOrId, contextObject); var databaseName = TryGetPropertyName(PropertyDatabaseName, contextObject); var connectionInfo = new ConnectionInfo(host, portPathOrId, databaseName); var segment = transaction.StartDatastoreSegment(instrumentedMethodCall.MethodCall, ParsedSqlStatement.FromOperation(DatastoreVendor.Redis, operation), connectionInfo); return(Delegates.GetDelegateFor(segment)); }
public AfterWrappedMethodDelegate BeforeWrappedMethod(InstrumentedMethodCall instrumentedMethodCall, IAgent agent, ITransaction transaction) { var operation = GetOperationName(instrumentedMethodCall.MethodCall); var segment = transaction.StartDatastoreSegment(instrumentedMethodCall.MethodCall, ParsedSqlStatement.FromOperation(DatastoreVendor.MongoDB, operation)); return(Delegates.GetDelegateFor(segment)); }
public AfterWrappedMethodDelegate BeforeWrappedMethod(InstrumentedMethodCall instrumentedMethodCall, IAgent agent, ITransaction transaction) { var operation = Common.GetRedisCommand(instrumentedMethodCall.MethodCall, AssemblyName); var connectionInfo = Common.GetConnectionInfoFromConnectionMultiplexer(instrumentedMethodCall.MethodCall, AssemblyName); var segment = transaction.StartDatastoreSegment(instrumentedMethodCall.MethodCall, ParsedSqlStatement.FromOperation(DatastoreVendor.Redis, operation), connectionInfo); return(Delegates.GetDelegateFor(segment)); }