Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default and specific request timeout

Usually it's desirable to have default timeout (e.g. 30s) that will be applied to all requests and can be overridden for particular longer requests (e.g. 600s).

There's no good way to specify default timeout in Http service, to my knowledge.

What is the way to approach this in HttpClient service? How to define a default timeout for all outgoing requests, that can be overriden for specific ones?

like image 358
Estus Flask Avatar asked Aug 29 '17 12:08

Estus Flask


People also ask

What is the default request timeout?

The default value is 100,000 milliseconds (100 seconds).

What is default timeout for request in Python?

The default timeout is None , which means it'll wait (hang) until the connection is closed.

What is the ideal timeout for HTTP request?

The default value is 60 seconds. If the value of this stanza entry is set to 0 (or not set), connection timeouts between data fragments are governed instead by the client-connect-timeout stanza entry. The exception to this rule occurs for responses returned over HTTP (TCP).

What is the default timeout for HTTP request angular?

In complement to the other answers, just beware that if you use the proxy config on the dev machine, the proxy's default timeout is 120 seconds (2 minutes).


2 Answers

It appears that without extending HttpClientModule classes, the only expected ways for interceptors to communicate with respective requests are params and headers objects.

Since timeout value is scalar, it can be safely provided as a custom header to the interceptor, where it can be decided if it's default or specific timeout that should be applied via RxJS timeout operator:

import { Inject, Injectable, InjectionToken } from '@angular/core'; import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; import { Observable } from 'rxjs'; import { timeout } from 'rxjs/operators';  export const DEFAULT_TIMEOUT = new InjectionToken<number>('defaultTimeout');  @Injectable() export class TimeoutInterceptor implements HttpInterceptor {   constructor(@Inject(DEFAULT_TIMEOUT) protected defaultTimeout: number) {   }    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {     const timeoutValue = req.headers.get('timeout') || this.defaultTimeout;     const timeoutValueNumeric = Number(timeoutValue);      return next.handle(req).pipe(timeout(timeoutValueNumeric));   } } 

This can be configured in your app module like:

providers: [   [{ provide: HTTP_INTERCEPTORS, useClass: TimeoutInterceptor, multi: true }],   [{ provide: DEFAULT_TIMEOUT, useValue: 30000 }] ], 

The request is then done with a custom timeout header

http.get('/your/url/here', { headers: new HttpHeaders({ timeout: `${20000}` }) }); 

Since headers are supposed to be strings, the timeout value should be converted to a string first.

Here is a demo.

Credits go to @RahulSingh and @Jota.Toledo for suggesting the idea of using interceptors with timeout.

like image 198
Estus Flask Avatar answered Oct 06 '22 07:10

Estus Flask


In complement to the other answers, just beware that if you use the proxy config on the dev machine, the proxy's default timeout is 120 seconds (2 minutes). For longer requests, you'll need to define a higher value in the configuration, or else none of these answers will work.

{   "/api": {     "target": "http://localhost:3000",     "secure": false,     "timeout": 360000   } } 
like image 22
Marcos Dimitrio Avatar answered Oct 06 '22 07:10

Marcos Dimitrio