@aimee-blue/ab-service-kit
Version:
Aimee Blue Service Template
1 lines • 4.93 kB
Source Map (JSON)
{"version":3,"sources":["../../src/shared/retryWithBackoff.ts"],"names":["timeBeforeNextRetry","opts","numberOfErrors","minWaitTime","waitTimeOnFirstError","Math","min","waitTimeOnBackoff","maxWaitTime","retryWithBackoff","optsRaw","shouldRetry","_info","resetErrorsOnNext","sourceDescription","logger","log","info","error","toFixed","recursiveObserve","errors","source","reset","pipe","stream","time","Promise","reject"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AACA;;AAqBA,SAASA,mBAAT,CAA6BC,IAA7B,EAAkDC,cAAlD,EAA0E;AACxE,SACED,IAAI,CAACE,WAAL,IACCD,cAAc,KAAK,CAAnB,GACGD,IAAI,CAACG,oBADR,GAEGC,IAAI,CAACC,GAAL,CAASL,IAAI,CAACM,iBAAL,GAAyBL,cAAlC,EAAkDD,IAAI,CAACO,WAAvD,CAHJ,CADF;AAMD;;AAEM,SAASC,gBAAT,CAA6BC,OAA7B,EAAkD;AAAA;;AACvD,QAAMT,IAAmB,GAAG;AAC1BU,IAAAA,WAAW,EAAEC,KAAK,IAAI;AACpB,aAAO,IAAP;AACD,KAHyB;AAI1BC,IAAAA,iBAAiB,EAAE,IAJO;AAK1BT,IAAAA,oBAAoB,EAAE,IAAI,IALA;AAM1BG,IAAAA,iBAAiB,EAAE,IAAI,IANG;AAO1BJ,IAAAA,WAAW,EAAE,CAPa;AAQ1BK,IAAAA,WAAW,EAAE,IAAI,EAAJ,GAAS,EAAT,GAAc,IARD;AAS1BM,IAAAA,iBAAiB,EAAE,SATO;AAU1B,OAAGJ;AAVuB,GAA5B;AAaA,QAAMK,MAAM,mBAAGd,IAAI,CAACc,MAAR,uDAAkB,kCAA9B;;AAEA,QAAMC,GAAG,GAAIC,IAAD,IAAsB;AAChCF,IAAAA,MAAM,CAACG,KAAP,CACG,WAAUjB,IAAI,CAACa,iBAAL,IAA0B,SAAU,eAC7CG,IAAI,CAACf,cACN,2BAA0B,CAACe,IAAI,CAACjB,mBAAL,GAA2B,IAA5B,EAAkCmB,OAAlC,CACzB,CADyB,CAEzB,KALJ,EAMEF,IAAI,CAACC,KANP;AAQD,GATD;;AAWA,QAAME,gBAAgB,GAAG,CACvBC,MADuB,EAEvBC,MAFuB,KAGL;AAClB,QAAIC,KAAK,GAAG,KAAZ;AACA,WAAOD,MAAM,CAACE,IAAP,CACLC,MAAM,IACJxB,IAAI,CAACY,iBAAL,GACIY,MAAM,CAACD,IAAP,CACE,oBAAI,MAAM;AACR;AACAD,MAAAA,KAAK,GAAG,IAAR;AACD,KAHD,CADF,CADJ,GAOIE,MATD,EAUL,2BAAYP,KAAD,IAAkB;AAC3B,wCAAcA,KAAd;AACA,YAAMhB,cAAc,GAAGqB,KAAK,GAAG,CAAH,GAAOF,MAAnC;AACA,YAAMK,IAAI,GAAG1B,mBAAmB,CAACC,IAAD,EAAOC,cAAc,GAAG,CAAxB,CAAhC;AACA,YAAMe,IAAI,GAAG;AACXC,QAAAA,KADW;AAEXhB,QAAAA,cAAc,EAAEA,cAAc,GAAG,CAFtB;AAGXF,QAAAA,mBAAmB,EAAE0B;AAHV,OAAb;AAKAV,MAAAA,GAAG,CAACC,IAAD,CAAH;AACA,aAAOhB,IAAI,CAACU,WAAL,CAAiBM,IAAjB,IACH,iBAAMS,IAAN,EAAYF,IAAZ,CACE,4BAAYJ,gBAAgB,CAAClB,cAAc,GAAG,CAAlB,EAAqBoB,MAArB,CAA5B,CADF,CADG,GAIH,gBAAKK,OAAO,CAACC,MAAR,CAAeV,KAAf,CAAL,CAJJ;AAKD,KAfD,CAVK,CAAP;AA2BD,GAhCD;;AAkCA,SAAQI,MAAD,IAA2BF,gBAAgB,CAAC,CAAD,EAAIE,MAAJ,CAAlD;AACD","sourcesContent":["import { Observable, timer, from } from 'rxjs';\nimport { catchError, switchMapTo, tap } from 'rxjs/operators';\nimport { registerError } from './registerError';\nimport { BasicLogger, defaultBasicLogger } from './logging';\n\ninterface IErrorInfo {\n error: Error;\n numberOfErrors: number;\n timeBeforeNextRetry: number;\n}\n\nexport type RetryOpts = Partial<IRetryOptsAll>;\n\ninterface IRetryOptsAll {\n shouldRetry: (info: IErrorInfo) => boolean;\n sourceDescription: string;\n resetErrorsOnNext: boolean;\n waitTimeOnBackoff: number;\n waitTimeOnFirstError: number;\n minWaitTime: number;\n maxWaitTime: number;\n logger?: BasicLogger;\n}\n\nfunction timeBeforeNextRetry(opts: IRetryOptsAll, numberOfErrors: number) {\n return (\n opts.minWaitTime +\n (numberOfErrors === 1\n ? opts.waitTimeOnFirstError\n : Math.min(opts.waitTimeOnBackoff * numberOfErrors, opts.maxWaitTime))\n );\n}\n\nexport function retryWithBackoff<T>(optsRaw?: RetryOpts) {\n const opts: IRetryOptsAll = {\n shouldRetry: _info => {\n return true;\n },\n resetErrorsOnNext: true,\n waitTimeOnFirstError: 1 * 1000,\n waitTimeOnBackoff: 5 * 1000,\n minWaitTime: 1,\n maxWaitTime: 1 * 60 * 60 * 1000,\n sourceDescription: 'process',\n ...optsRaw,\n };\n\n const logger = opts.logger ?? defaultBasicLogger();\n\n const log = (info: IErrorInfo) => {\n logger.error(\n `💥 The ${opts.sourceDescription || 'process'} has failed ${\n info.numberOfErrors\n } time(s). Will retry in ${(info.timeBeforeNextRetry / 1000).toFixed(\n 2\n )}s. `,\n info.error\n );\n };\n\n const recursiveObserve = (\n errors: number,\n source: Observable<T>\n ): Observable<T> => {\n let reset = false;\n return source.pipe(\n stream =>\n opts.resetErrorsOnNext\n ? stream.pipe(\n tap(() => {\n // if we got at least one element consider this a success\n reset = true;\n })\n )\n : stream,\n catchError((error: Error) => {\n registerError(error);\n const numberOfErrors = reset ? 0 : errors;\n const time = timeBeforeNextRetry(opts, numberOfErrors + 1);\n const info = {\n error,\n numberOfErrors: numberOfErrors + 1,\n timeBeforeNextRetry: time,\n };\n log(info);\n return opts.shouldRetry(info)\n ? timer(time).pipe(\n switchMapTo(recursiveObserve(numberOfErrors + 1, source))\n )\n : from(Promise.reject(error));\n })\n );\n };\n\n return (source: Observable<T>) => recursiveObserve(0, source);\n}\n"],"file":"retryWithBackoff.js"}