Async Service Methods and the Logger

I implemented an ORMLite IRequestLogger. I have an Async service that uses AutoQuery and it appears that when the first await is hit in that Async service (well before the API has returned a response), the logger code fires and attempts to log the API request, and the Log method gets called with response.Status property value of WaitingForActivation and a response.Result of null. How do I stop the Logger from attempting to log until the async API has completed?

thanks!

Can you provide a sample of async service and your logger registration we can look into?

public class MyService : Service
    {
        public IAutoQueryDb AutoQuery { get; set; }
        public async Task<ResponseDTO> Any(RequestDTO request)
        {
            var result = new ResponseDTO {SomePropertyValue = await Db.SingleByIdAsync<SomeObject>(request.Id).ConfigureAwait(false)};
//more activity
}}

//logger registration:
Plugins.Add(new RequestLogsFeature {
                    RequestLogger = new EncryptedDBRequestLogger(dbFactory.Open()) { EncryptRequestBodyForRequestDtoTypes = new System.Type[] { typeof(CreatePaymentReq) } },
                    EnableErrorTracking = true,
                    EnableResponseTracking = true,
                    ExcludeRequestDtoTypes = new System.Type[] { typeof(OpenApiSpecification), typeof(RequestLogs)}
                });

Any progress here? It seems this issue is calling my API calls to fail intermittently with “An asynchronous module or handler completed while an asynchronous operation was still pending.” Since the logger code exits prior to the API call returning.

If it helps at all, here is my Log implementation:

public virtual async void Log(IRequest request, object requestDto, object response, TimeSpan requestDuration)
        {
            var requestType = requestDto?.GetType();
            if (ExcludeRequestType(requestType))
                return;
            var entry = CreateEntry(request, requestDto, response, requestDuration, requestType);
            await Db.InsertAsync(entry).ConfigureAwait(false);
        }

You can’t log asynchronously, Log is a void method, it doesn’t return a Task. Change it to use Db.Insert() instead.

The issue with that is I get a deadlock because the API service is Async, which gives control to the Log when it tries to write to the DB, and therefore the log attempts to execute but stalls because it doesn’t have the return value yet from the API call.

Can you try again with the latest v4.5.13 that’s on MyGet, async requests should now only be getting logged when the async Service completes.

that works - thanks for fixing!

1 Like