func (c *Coordinator) onStepBarrierChange(step int, m *donut.SafeMap) { if m.Len() == c.workers.Len() { defer m.Clear() barrierName := "superstep-" + strconv.Itoa(step) // the barrier is full, collect information and launch the next step c.graph.globalStat.reset() c.graph.globalStat.step = step // collect and unmarshal data for all entries in the barrier lm := m.GetCopy() for k := range lm { if data, _, err := c.zk.Get(path.Join(c.barriersPath, barrierName, k)); err == nil { var info map[string]interface{} if err := json.Unmarshal([]byte(data), &info); err != nil { panic(err) } c.graph.globalStat.active += int(info["active"].(float64)) c.graph.globalStat.msgs += int(info["msgs"].(float64)) } else { panic(err) } } // kill the watcher on this barrier c.watchers[barrierName] <- 1 delete(c.watchers, barrierName) if c.graph.globalStat.active == 0 && c.graph.globalStat.msgs == 0 { atomic.StoreInt32(&c.state, WriteState) go c.createWriteWork() } else { go c.createStepWork(step + 1) } } else { log.Printf("step barrier change: %d entries out of %d", m.Len(), c.workers.Len()) } }