Nakorr
Nakorr

Reputation: 75

Set custom timeout using Google Analytics v3 .Net class library

I'm attempting to use Google's .Net client library (Analytics v3) to get data using my GA service account. Everything is working fine, except I am receiving occasional timeouts during the requests to the GA API (using the client library). I would like to adjust the timeout logic (and add retry logic through the library, if possible - but this is a smaller concern).

Currently I cannot figure out how to modify the timeout settings through the client library. From reading their source code (as I cannot find anything resembling useful documentation on the .net side of the house), it is looking like I'll need to implement "IConfigurableHttpClientInitializer". Below is an example of what I was thinking of, but I'm not sure if it is correct or how to integrate it with my existing code. An extract of my relevant code is also below.

Class to set timeout

public class TimeoutInitializer : IConfigurableHttpClientInitializer
{
    public void Initialize(ConfigurableHttpClient httpClient)
    {
        httpClient.Timeout = TimeSpan.FromMinutes(3);
    }
}

Existing Code

private async Task<GaData> GetAnalyticsData(string profileId, DateTime begin, DateTime end, string metrics, string dimensions)
    {
        GoogleCredential credential = AnalyticsHelper.GetCredentials(options.GoogleAnalyticsOptions);

        var service = new AnalyticsService(new BaseClientService.Initializer() { HttpClientInitializer = credential });
        DataResource.GaResource.GetRequest request = service.Data.Ga.Get($"ga:{profileId}", AnalyticsHelper.FormatDate(begin), AnalyticsHelper.FormatDate(end), metrics);
        if (!string.IsNullOrEmpty(dimensions))
        {
            request.Dimensions = dimensions;
        }

        return await request.ExecuteAsync();
    }

public class AnalyticsHelper
{
    public static GoogleCredential GetCredentials(AnalyticsOptions options)
    {
        using (Stream stream = new FileStream(options.ServiceAccountKeyPath, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            return GoogleCredential.FromStream(stream).CreateScoped(AnalyticsService.Scope.AnalyticsReadonly);
        }
    }
}

I am thinking that

var service = new AnalyticsService(new BaseClientService.Initializer() { HttpClientInitializer = credential });

would be replaced with something like

var service = new AnalyticsService(new BaseClientService.Initializer() { HttpClientInitializer = new TimeoutInitializer() });

However, I'm not positive and am unsure of how to combine the original credential logic with it. I considered creating a new class which implements GoogleCredential, but I feel there has to be a better way.

Any pointers would be greatly appreciated. I couldn't find any other posts related to this same problem. I'm going to continue to read through the source and attempt to decipher the correct approach for this, and will update this post if I find a solution.

Upvotes: 0

Views: 913

Answers (1)

Chris
Chris

Reputation: 1705

After creating the service as normal with the credential as the initializer:

var service = new AnalyticsService(new BaseClientService.Initializer()
{
    HttpClientInitializer = credential
});

Then access the HttpClient directly and set the timeout:

service.HttpClient.Timeout = TimeSpan.FromMinutes(3);

Upvotes: 6

Related Questions