1- import { ISplit } from '../../../dtos/types' ;
1+ import { IRBSegment , ISplit } from '../../../dtos/types' ;
2+ import { STREAMING_PARSING_SPLIT_UPDATE } from '../../../logger/constants' ;
23import { ILogger } from '../../../logger/types' ;
34import { SDK_SPLITS_ARRIVED } from '../../../readiness/constants' ;
45import { ISplitsEventEmitter } from '../../../readiness/types' ;
@@ -7,94 +8,120 @@ import { ITelemetryTracker } from '../../../trackers/types';
78import { Backoff } from '../../../utils/Backoff' ;
89import { SPLITS } from '../../../utils/constants' ;
910import { ISegmentsSyncTask , ISplitsSyncTask } from '../../polling/types' ;
11+ import { RBSEGMENT_UPDATE } from '../constants' ;
12+ import { parseFFUpdatePayload } from '../parseUtils' ;
1013import { ISplitKillData , ISplitUpdateData } from '../SSEHandler/types' ;
1114import { FETCH_BACKOFF_BASE , FETCH_BACKOFF_MAX_WAIT , FETCH_BACKOFF_MAX_RETRIES } from './constants' ;
1215import { IUpdateWorker } from './types' ;
1316
1417/**
1518 * SplitsUpdateWorker factory
1619 */
17- export function SplitsUpdateWorker ( log : ILogger , splitsCache : ISplitsCacheSync , splitsSyncTask : ISplitsSyncTask , splitsEventEmitter : ISplitsEventEmitter , telemetryTracker : ITelemetryTracker , segmentsSyncTask ?: ISegmentsSyncTask ) : IUpdateWorker < [ updateData : ISplitUpdateData , payload ?: ISplit ] > & { killSplit ( event : ISplitKillData ) : void } {
20+ export function SplitsUpdateWorker ( log : ILogger , splitsCache : ISplitsCacheSync , splitsSyncTask : ISplitsSyncTask , splitsEventEmitter : ISplitsEventEmitter , telemetryTracker : ITelemetryTracker , segmentsSyncTask ?: ISegmentsSyncTask ) : IUpdateWorker < [ updateData : ISplitUpdateData ] > & { killSplit ( event : ISplitKillData ) : void } {
1821
19- let maxChangeNumber = 0 ;
20- let handleNewEvent = false ;
21- let isHandlingEvent : boolean ;
22- let cdnBypass : boolean ;
23- let payload : ISplit | undefined ;
24- const backoff = new Backoff ( __handleSplitUpdateCall , FETCH_BACKOFF_BASE , FETCH_BACKOFF_MAX_WAIT ) ;
22+ function SplitsUpdateWorker ( ) {
23+ let maxChangeNumber = 0 ;
24+ let handleNewEvent = false ;
25+ let isHandlingEvent : boolean ;
26+ let cdnBypass : boolean ;
27+ let payload : ISplit | IRBSegment | undefined ;
28+ const backoff = new Backoff ( __handleSplitUpdateCall , FETCH_BACKOFF_BASE , FETCH_BACKOFF_MAX_WAIT ) ;
2529
26- function __handleSplitUpdateCall ( ) {
27- isHandlingEvent = true ;
28- if ( maxChangeNumber > splitsCache . getChangeNumber ( ) ) {
29- handleNewEvent = false ;
30- const splitUpdateNotification = payload ? { payload, changeNumber : maxChangeNumber } : undefined ;
31- // fetch splits revalidating data if cached
32- splitsSyncTask . execute ( true , cdnBypass ? maxChangeNumber : undefined , splitUpdateNotification ) . then ( ( ) => {
33- if ( ! isHandlingEvent ) return ; // halt if `stop` has been called
34- if ( handleNewEvent ) {
35- __handleSplitUpdateCall ( ) ;
36- } else {
37- if ( splitUpdateNotification ) telemetryTracker . trackUpdatesFromSSE ( SPLITS ) ;
38- // fetch new registered segments for server-side API. Not retrying on error
39- if ( segmentsSyncTask ) segmentsSyncTask . execute ( true ) ;
30+ function __handleSplitUpdateCall ( ) {
31+ isHandlingEvent = true ;
32+ if ( maxChangeNumber > splitsCache . getChangeNumber ( ) ) {
33+ handleNewEvent = false ;
34+ const splitUpdateNotification = payload ? { payload, changeNumber : maxChangeNumber } : undefined ;
35+ // fetch splits revalidating data if cached
36+ splitsSyncTask . execute ( true , cdnBypass ? maxChangeNumber : undefined , splitUpdateNotification ) . then ( ( ) => {
37+ if ( ! isHandlingEvent ) return ; // halt if `stop` has been called
38+ if ( handleNewEvent ) {
39+ __handleSplitUpdateCall ( ) ;
40+ } else {
41+ if ( splitUpdateNotification ) telemetryTracker . trackUpdatesFromSSE ( SPLITS ) ;
42+ // fetch new registered segments for server-side API. Not retrying on error
43+ if ( segmentsSyncTask ) segmentsSyncTask . execute ( true ) ;
4044
41- const attempts = backoff . attempts + 1 ;
45+ const attempts = backoff . attempts + 1 ;
4246
43- if ( maxChangeNumber <= splitsCache . getChangeNumber ( ) ) {
44- log . debug ( `Refresh completed${ cdnBypass ? ' bypassing the CDN' : '' } in ${ attempts } attempts.` ) ;
45- isHandlingEvent = false ;
46- return ;
47- }
47+ if ( maxChangeNumber <= splitsCache . getChangeNumber ( ) ) {
48+ log . debug ( `Refresh completed${ cdnBypass ? ' bypassing the CDN' : '' } in ${ attempts } attempts.` ) ;
49+ isHandlingEvent = false ;
50+ return ;
51+ }
4852
49- if ( attempts < FETCH_BACKOFF_MAX_RETRIES ) {
50- backoff . scheduleCall ( ) ;
51- return ;
52- }
53+ if ( attempts < FETCH_BACKOFF_MAX_RETRIES ) {
54+ backoff . scheduleCall ( ) ;
55+ return ;
56+ }
5357
54- if ( cdnBypass ) {
55- log . debug ( `No changes fetched after ${ attempts } attempts with CDN bypassed.` ) ;
56- isHandlingEvent = false ;
57- } else {
58- backoff . reset ( ) ;
59- cdnBypass = true ;
60- __handleSplitUpdateCall ( ) ;
58+ if ( cdnBypass ) {
59+ log . debug ( `No changes fetched after ${ attempts } attempts with CDN bypassed.` ) ;
60+ isHandlingEvent = false ;
61+ } else {
62+ backoff . reset ( ) ;
63+ cdnBypass = true ;
64+ __handleSplitUpdateCall ( ) ;
65+ }
6166 }
62- }
63- } ) ;
64- } else {
65- isHandlingEvent = false ;
67+ } ) ;
68+ } else {
69+ isHandlingEvent = false ;
70+ }
6671 }
67- }
6872
69- /**
70- * Invoked by NotificationProcessor on SPLIT_UPDATE event
71- *
72- * @param changeNumber - change number of the SPLIT_UPDATE notification
73- */
74- function put ( { changeNumber, pcn } : ISplitUpdateData , _payload ?: ISplit ) {
75- const currentChangeNumber = splitsCache . getChangeNumber ( ) ;
73+ return {
74+ /**
75+ * Invoked by NotificationProcessor on SPLIT_UPDATE or RBSEGMENT_UPDATE event
76+ *
77+ * @param changeNumber - change number of the notification
78+ */
79+ put ( { changeNumber, pcn } : ISplitUpdateData , _payload ?: ISplit | IRBSegment ) {
80+ const currentChangeNumber = splitsCache . getChangeNumber ( ) ;
7681
77- if ( changeNumber <= currentChangeNumber || changeNumber <= maxChangeNumber ) return ;
82+ if ( changeNumber <= currentChangeNumber || changeNumber <= maxChangeNumber ) return ;
7883
79- maxChangeNumber = changeNumber ;
80- handleNewEvent = true ;
81- cdnBypass = false ;
82- payload = undefined ;
84+ maxChangeNumber = changeNumber ;
85+ handleNewEvent = true ;
86+ cdnBypass = false ;
87+ payload = undefined ;
8388
84- if ( _payload && currentChangeNumber === pcn ) {
85- payload = _payload ;
86- }
89+ if ( _payload && currentChangeNumber === pcn ) {
90+ payload = _payload ;
91+ }
8792
88- if ( backoff . timeoutID || ! isHandlingEvent ) __handleSplitUpdateCall ( ) ;
89- backoff . reset ( ) ;
93+ if ( backoff . timeoutID || ! isHandlingEvent ) __handleSplitUpdateCall ( ) ;
94+ backoff . reset ( ) ;
95+ } ,
96+ stop ( ) {
97+ isHandlingEvent = false ;
98+ backoff . reset ( ) ;
99+ }
100+ } ;
90101 }
91102
103+ const ff = SplitsUpdateWorker ( ) ;
104+ const rbs = SplitsUpdateWorker ( ) ;
105+
92106 return {
93- put,
107+ put ( parsedData ) {
108+ if ( parsedData . d && parsedData . c !== undefined ) {
109+ try {
110+ const payload = parseFFUpdatePayload ( parsedData . c , parsedData . d ) ;
111+ if ( payload ) {
112+ ( parsedData . type === RBSEGMENT_UPDATE ? rbs : ff ) . put ( parsedData , payload ) ;
113+ return ;
114+ }
115+ } catch ( e ) {
116+ log . warn ( STREAMING_PARSING_SPLIT_UPDATE , [ parsedData . type , e ] ) ;
117+ }
118+ }
119+ ( parsedData . type === RBSEGMENT_UPDATE ? rbs : ff ) . put ( parsedData ) ;
120+ } ,
94121 /**
95122 * Invoked by NotificationProcessor on SPLIT_KILL event
96123 *
97- * @param changeNumber - change number of the SPLIT_UPDATE notification
124+ * @param changeNumber - change number of the notification
98125 * @param splitName - name of split to kill
99126 * @param defaultTreatment - default treatment value
100127 */
@@ -104,12 +131,12 @@ export function SplitsUpdateWorker(log: ILogger, splitsCache: ISplitsCacheSync,
104131 splitsEventEmitter . emit ( SDK_SPLITS_ARRIVED , true ) ;
105132 }
106133 // queues the SplitChanges fetch (only if changeNumber is newer)
107- put ( { changeNumber } as ISplitUpdateData ) ;
134+ ff . put ( { changeNumber } as ISplitUpdateData ) ;
108135 } ,
109136
110137 stop ( ) {
111- isHandlingEvent = false ;
112- backoff . reset ( ) ;
138+ ff . stop ( ) ;
139+ rbs . stop ( ) ;
113140 }
114141 } ;
115142}
0 commit comments