@@ -82,7 +82,23 @@ public RefreshableSplitFetcher(SplitChangeFetcher splitChangeFetcher, SplitParse
8282
8383 @ Override
8484 public void forceRefresh () {
85- run ();
85+ _log .debug ("Force Refresh splits starting ..." );
86+ try {
87+ while (true ) {
88+ long start = _changeNumber .get ();
89+ runWithoutExceptionHandling ();
90+ long end = _changeNumber .get ();
91+
92+ if (start >= end ) {
93+ break ;
94+ }
95+ }
96+ } catch (InterruptedException e ) {
97+ _log .warn ("Interrupting split fetcher task" );
98+ Thread .currentThread ().interrupt ();
99+ } catch (Throwable t ) {
100+ _log .error ("RefreshableSplitFetcher failed: " + t .getMessage ());
101+ }
86102 }
87103
88104 @ Override
@@ -160,103 +176,101 @@ public void run() {
160176 }
161177
162178 public void runWithoutExceptionHandling () throws InterruptedException {
163- while (true ) {
164- SplitChange change = _splitChangeFetcher .fetch (_changeNumber .get ());
179+ SplitChange change = _splitChangeFetcher .fetch (_changeNumber .get ());
165180
166- if (change == null ) {
167- throw new IllegalStateException ("SplitChange was null" );
168- }
181+ if (change == null ) {
182+ throw new IllegalStateException ("SplitChange was null" );
183+ }
169184
170- if (change .till == _changeNumber .get ()) {
171- // no change.
172- break ;
173- }
185+ if (change .till == _changeNumber .get ()) {
186+ // no change.
187+ return ;
188+ }
174189
175- if (change .since != _changeNumber .get () || change .till < _changeNumber .get ()) {
190+ if (change .since != _changeNumber .get () || change .till < _changeNumber .get ()) {
191+ // some other thread may have updated the shared state. exit
192+ return ;
193+ }
194+
195+ if (change .splits .isEmpty ()) {
196+ // there are no changes. weird!
197+ _changeNumber .set (change .till );
198+ return ;
199+ }
200+
201+ synchronized (_lock ) {
202+ // check state one more time.
203+ if (change .since != _changeNumber .get ()
204+ || change .till < _changeNumber .get ()) {
176205 // some other thread may have updated the shared state. exit
177- break ;
206+ return ;
178207 }
179208
180- if (change .splits .isEmpty ()) {
181- // there are no changes. weird!
182- _changeNumber .set (change .till );
183- break ;
184- }
209+ Set <String > toRemove = Sets .newHashSet ();
210+ Map <String , ParsedSplit > toAdd = Maps .newHashMap ();
211+ List <String > trafficTypeNamesToRemove = Lists .newArrayList ();
212+ List <String > trafficTypeNamesToAdd = Lists .newArrayList ();
185213
186- synchronized (_lock ) {
187- // check state one more time.
188- if (change .since != _changeNumber .get ()
189- || change .till < _changeNumber .get ()) {
190- // some other thread may have updated the shared state. exit
191- break ;
214+ for (Split split : change .splits ) {
215+ if (Thread .currentThread ().isInterrupted ()) {
216+ throw new InterruptedException ();
192217 }
193218
194- Set <String > toRemove = Sets .newHashSet ();
195- Map <String , ParsedSplit > toAdd = Maps .newHashMap ();
196- List <String > trafficTypeNamesToRemove = Lists .newArrayList ();
197- List <String > trafficTypeNamesToAdd = Lists .newArrayList ();
198-
199- for (Split split : change .splits ) {
200- if (Thread .currentThread ().isInterrupted ()) {
201- throw new InterruptedException ();
202- }
203-
204- if (split .status != Status .ACTIVE ) {
205- // archive.
206- toRemove .add (split .name );
207- if (split .trafficTypeName != null ) {
208- trafficTypeNamesToRemove .add (split .trafficTypeName );
209- }
210- continue ;
211- }
212-
213- ParsedSplit parsedSplit = _parser .parse (split );
214- if (parsedSplit == null ) {
215- _log .info ("We could not parse the experiment definition for: " + split .name + " so we are removing it completely to be careful" );
216- toRemove .add (split .name );
217- if (split .trafficTypeName != null ) {
218- trafficTypeNamesToRemove .add (split .trafficTypeName );
219- }
220- continue ;
221- }
222-
223- toAdd .put (split .name , parsedSplit );
224-
225- // If the split already exists, this is either an update, or the split has been
226- // deleted and recreated (possibly with a different traffic type).
227- // If it's an update, the traffic type should NOT be increased.
228- // If it's deleted & recreated, the old one should be decreased and the new one increased.
229- // To handle both cases, we simply delete the old one if the split is present.
230- // The new one is always increased.
231- ParsedSplit current = _concurrentMap .get (split .name );
232- if (current != null && current .trafficTypeName () != null ) {
233- trafficTypeNamesToRemove .add (current .trafficTypeName ());
219+ if (split .status != Status .ACTIVE ) {
220+ // archive.
221+ toRemove .add (split .name );
222+ if (split .trafficTypeName != null ) {
223+ trafficTypeNamesToRemove .add (split .trafficTypeName );
234224 }
225+ continue ;
226+ }
235227
228+ ParsedSplit parsedSplit = _parser .parse (split );
229+ if (parsedSplit == null ) {
230+ _log .info ("We could not parse the experiment definition for: " + split .name + " so we are removing it completely to be careful" );
231+ toRemove .add (split .name );
236232 if (split .trafficTypeName != null ) {
237- trafficTypeNamesToAdd .add (split .trafficTypeName );
233+ trafficTypeNamesToRemove .add (split .trafficTypeName );
238234 }
235+ continue ;
239236 }
240237
241- _concurrentMap .putAll (toAdd );
242- _concurrentTrafficTypeNameSet .addAll (trafficTypeNamesToAdd );
243- //removeAll does not work here, since it wont remove all the occurrences, just one
244- Multisets .removeOccurrences (_concurrentTrafficTypeNameSet , trafficTypeNamesToRemove );
245-
246- for (String remove : toRemove ) {
247- _concurrentMap .remove (remove );
238+ toAdd .put (split .name , parsedSplit );
239+
240+ // If the split already exists, this is either an update, or the split has been
241+ // deleted and recreated (possibly with a different traffic type).
242+ // If it's an update, the traffic type should NOT be increased.
243+ // If it's deleted & recreated, the old one should be decreased and the new one increased.
244+ // To handle both cases, we simply delete the old one if the split is present.
245+ // The new one is always increased.
246+ ParsedSplit current = _concurrentMap .get (split .name );
247+ if (current != null && current .trafficTypeName () != null ) {
248+ trafficTypeNamesToRemove .add (current .trafficTypeName ());
248249 }
249250
250- if (! toAdd . isEmpty () ) {
251- _log . debug ( "Updated features: " + toAdd . keySet () );
251+ if (split . trafficTypeName != null ) {
252+ trafficTypeNamesToAdd . add ( split . trafficTypeName );
252253 }
254+ }
253255
254- if (!toRemove .isEmpty ()) {
255- _log .debug ("Deleted features: " + toRemove );
256- }
256+ _concurrentMap .putAll (toAdd );
257+ _concurrentTrafficTypeNameSet .addAll (trafficTypeNamesToAdd );
258+ //removeAll does not work here, since it wont remove all the occurrences, just one
259+ Multisets .removeOccurrences (_concurrentTrafficTypeNameSet , trafficTypeNamesToRemove );
257260
258- _changeNumber .set (change .till );
261+ for (String remove : toRemove ) {
262+ _concurrentMap .remove (remove );
259263 }
264+
265+ if (!toAdd .isEmpty ()) {
266+ _log .debug ("Updated features: " + toAdd .keySet ());
267+ }
268+
269+ if (!toRemove .isEmpty ()) {
270+ _log .debug ("Deleted features: " + toRemove );
271+ }
272+
273+ _changeNumber .set (change .till );
260274 }
261275 }
262276}
0 commit comments