Github user zd-project commented on a diff in the pull request:

    https://github.com/apache/storm/pull/2800#discussion_r212801285
  
    --- Diff: storm-client/src/jvm/org/apache/storm/stats/StatsUtil.java ---
    @@ -1565,23 +1565,26 @@ public static ComponentPageInfo aggCompExecsStats(
         public static void updateHeartbeatCache(Map<List<Integer>, Map<String, 
Object>> cache,
                                                 Map<List<Integer>, Map<String, 
Object>> executorBeats, Set<List<Integer>> executors,
                                                 Integer timeout) {
    -        //if not executor beats, refresh is-timed-out of the cache which 
is done by master
    +        assert cache instanceof ConcurrentMap;
    +        //Should we enforce update-if-newer policy?
             if (executorBeats == null) {
    -            for (Map.Entry<List<Integer>, Map<String, Object>> 
executorbeat : cache.entrySet()) {
    -                Map<String, Object> beat = executorbeat.getValue();
    +            //If not executor beats, refresh is-timed-out of the cache 
which is done by master
    --- End diff --
    
    This is actually where the `ConcurrentModificationException` is thrown. 
Notice that the old code invokes both `cache.entrySet()` and `cache.put()` in 
this method. Since it's exposed through thrift, it's possible to have 
`ConcurrentModificationException`. Also see travis log here for an example: 
https://travis-ci.org/apache/storm/jobs/408719153#L1897


---

Reply via email to