Skip to content

Instantly share code, notes, and snippets.

@alex-okrushko
Created May 23, 2018 03:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save alex-okrushko/9fb74b16e5756640ffb226c1508e462c to your computer and use it in GitHub Desktop.
Save alex-okrushko/9fb74b16e5756640ffb226c1508e462c to your computer and use it in GitHub Desktop.
Exponential backoff retry - example with fake service
import { Component } from '@angular/core';
import { of } from 'rxjs';
import { tap, switchMap} from 'rxjs/operators';
import { retryBackoff } from 'backoff-rxjs';
import { BackendService, HttpError } from './backend.service';
export const INIT_INTERVAL_MS = 100; // 100 ms
export const MAX_INTERVAL_MS = 20 * 1000; // 20 sec
@Component({
selector: 'my-app',
template: 'Open console :)',
})
export class AppComponent {
constructor(private readonly service: BackendService) { }
message = of('Call me!').pipe(
tap(console.log),
switchMap(() => this.service.callBackend()),
retryBackoff<HttpError>({
initialInterval: INIT_INTERVAL_MS,
maxInterval: MAX_INTERVAL_MS,
cancelRetry: (e) => e.status === '404',
}),
// Could also be used as
// exponentialBackoffRetry({ initialInterval: 100 }),
// or
// exponentialBackoffRetry({ initialInterval: 100, maxAttempts: 12}),
).subscribe(
msg => { console.log('success', msg) },
err => { console.log('error', err) },
() => { console.log('Complete!') });
}
import { Injectable } from '@angular/core';
import { of, throwError, defer } from 'rxjs';
export interface HttpError {
error: string,
status: string,
}
const ERROR_404: HttpError = { error: 'No need to try anymore', status: '404' };
const ERROR_503: HttpError = { error: 'Try again?', status: '503' };
@Injectable()
export class BackendService {
retries = 0;
/**
* Fake backend responses.
* Fails with 503 until 10-th retry
* Fails with 404 on 5-th retry
* Succeeds on 10+
*/
callBackend() {
this.retries++;
const result$ = (this.retries === 10)
? of({ data: 'Success!', status: '200' })
: (this.retries === 5)
? throwError(ERROR_404)
: throwError(ERROR_503);
return defer(() => result$);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment