Vonage/vonage-dotnet-sdk

Please add http request times out feature

brucehu123 opened this issue · 3 comments

Is your feature request related to a problem? Please describe.
The default value is 100,000 milliseconds (100 seconds) for HttpClient. this value is too big for us,We want to customize this timeout value.

Describe the solution you'd like
This Comment mentioned that

mainly because the class ApiRequest has changed a lot since then. Still, this feature must find its way to the SDK. I will have to find a way to do this clean, given that new API features do not use ApiRequest at all.

I would like to setting the feature in configuration

So,we should modifiy Configuration.cs

   /// <summary>
    ///  Retrieves the HttpClient Timeout.
    /// </summary>
    public double? Timeout => double.TryParse(this.Settings["appSettings:Vonage.RequestsTimeout"], out var timeout) ? timeout : null;

    /// <summary>
    ///     Retrieves a configured HttpClient.
    /// </summary>
    public HttpClient Client =>
        RequestsPerSecond
            .Map(BuildSemaphore)
            .Map(this.GetThrottlingMessageHandler)
            .Match(some =>
            {
                var client = new HttpClient(some);
                if (this.Timeout != null)
                {
                    client.Timeout = TimeSpan.FromMilliseconds(this.Timeout.Value);
                }
                return client;
            }, this.BuildDefaultClient);

    private HttpClient BuildDefaultClient()
    {
        var client = this.ClientHandler == null
            ? new HttpClient()
            : new HttpClient(this.ClientHandler);
        if (this.Timeout != null)
        {
            client.Timeout = TimeSpan.FromMilliseconds(this.Timeout.Value);
        }
        return client;
    }

and VonageClient.cs

private VonageHttpClientConfiguration BuildConfiguration(Uri baseUri, double? timeout = null) =>
         new(
             InitializeHttpClient(baseUri, timeout),
             this.Credentials.GetAuthenticationHeader(),
             this.Credentials.GetUserAgent());

    private Configuration GetConfiguration() => this.configuration.IfNone(Configuration.Instance);

    private static HttpClient InitializeHttpClient(Uri baseUri, double? timeout)
    {
        var client = new HttpClient(new HttpClientHandler())
        {
            BaseAddress = baseUri,
        };

        if (timeout != null)
        {
            client.Timeout = TimeSpan.FromMilliseconds(timeout.Value);
        }

        client.DefaultRequestHeaders.Add("Accept", "application/json");
        return client;
    }

    private void PropagateCredentials()
    {
        this.AccountClient = new AccountClient(this.Credentials, this.GetConfiguration(), this.timeProvider);
        this.ApplicationClient = new ApplicationClient(this.Credentials, this.GetConfiguration(), this.timeProvider);
        this.VoiceClient = new VoiceClient(this.Credentials, this.GetConfiguration(), this.timeProvider);
        this.ConversionClient = new ConversionClient(this.Credentials, this.GetConfiguration(), this.timeProvider);
        this.NumbersClient = new NumbersClient(this.Credentials, this.GetConfiguration(), this.timeProvider);
        this.NumberInsightClient =
            new NumberInsightClient(this.Credentials, this.GetConfiguration(), this.timeProvider);
        this.VerifyClient = new VerifyClient(this.Credentials, this.GetConfiguration(), this.timeProvider);
        this.ShortCodesClient = new ShortCodesClient(this.Credentials, this.GetConfiguration(), this.timeProvider);
        this.RedactClient = new RedactClient(this.Credentials, this.GetConfiguration(), this.timeProvider);
        this.SmsClient = new SmsClient(this.Credentials, this.GetConfiguration(), this.timeProvider);
        this.PricingClient = new PricingClient(this.Credentials, this.GetConfiguration(), this.timeProvider);
        this.MessagesClient = new MessagesClient(this.Credentials, this.GetConfiguration(), this.timeProvider);
        this.VerifyV2Client = new VerifyV2Client(this.BuildConfiguration(this.GetConfiguration().NexmoApiUrl, this.GetConfiguration().Timeout));
        this.SubAccountsClient = new SubAccountsClient(this.BuildConfiguration(this.GetConfiguration().NexmoApiUrl, this.GetConfiguration().Timeout),
            this.Credentials.ApiKey);
        this.UsersClient = new UsersClient(this.BuildConfiguration(this.GetConfiguration().NexmoApiUrl, this.GetConfiguration().Timeout));
        this.MeetingsClient = new MeetingsClient(this.BuildConfiguration(this.GetConfiguration().EuropeApiUrl, this.GetConfiguration().Timeout),
            new FileSystem());
        this.ProactiveConnectClient =
            new ProactiveConnectClient(this.BuildConfiguration(this.GetConfiguration().EuropeApiUrl, this.GetConfiguration().Timeout));
    }
Tr00d commented

Hi @brucehu123,

Thanks for raising that one.
Indeed, we had a PR about that, but it has been hanging for a while. The main file changed too much to approve it.

Until now, this feature wasn't on the radar. I'll put it on my backlog; I may have room to work on it during the following weeks.

I'll be in touch.
Cheers!

Tr00d commented

Hi @brucehu123,

With release v6.11.0, you're now able to define a custom timeout (in seconds) from the configuration file using the key Vonage.RequestTimeout. This is an optional configuration value; if a value isn't specified, the client will use the default timeout value.

So that you know, the timeout will be applied for all requests. Currently, it is impossible to define a timeout per request.

Let me know if this suits you.
Cheers!

Thank you for your great job! That is suit me perfectly!