func (a *LeaderActor) Running() dfa.Letter { ticker := time.NewTicker(30 * time.Second) defer ticker.Stop() a.state = NewLeaderState() s := condition.NewState(a.grid.Etcd(), 10*time.Minute, a.grid.Name(), a.flow.Name(), "state", a.ID()) defer s.Stop() if err := s.Init(a.state); err != nil { if _, err := s.Fetch(a.state); err != nil { return FetchStateFailure } } log.Printf("%v: running with state: %v, index: %v", a.ID(), a.state, s.Index()) w := condition.NewCountWatch(a.grid.Etcd(), a.grid.Name(), a.flow.Name(), "finished") defer w.Stop() finished := w.WatchUntil(a.conf.NrConsumers + a.conf.NrProducers) for { select { case <-a.exit: if _, err := s.Store(a.state); err != nil { log.Printf("%v: failed to save state: %v", a, err) } return Exit case <-a.chaos.C: if _, err := s.Store(a.state); err != nil { log.Printf("%v: failed to save state: %v", a, err) } return Failure case <-ticker.C: if err := a.started.Alive(); err != nil { return Failure } if _, err := s.Store(a.state); err != nil { return Failure } case <-finished: return EverybodyFinished case err := <-w.WatchError(): log.Printf("%v: error: %v", a, err) return Failure case m := <-a.rx.Msgs(): switch m := m.(type) { case ResultMsg: if strings.Contains(m.From, "producer") { a.state.ProducerCounts[m.Producer] = m.Count a.state.ProducerDurations[m.Producer] = m.Duration } if strings.Contains(m.From, "consumer") { a.state.ConsumerCounts[m.Producer] += m.Count } } } } }
func (a *ProducerActor) Running() dfa.Letter { ticker := time.NewTicker(30 * time.Second) defer ticker.Stop() a.state = NewProducerState() s := condition.NewState(a.grid.Etcd(), 30*time.Minute, a.grid.Name(), a.flow.Name(), "state", a.ID()) defer s.Stop() if err := s.Init(a.state); err != nil { if _, err := s.Fetch(a.state); err != nil { return FetchStateFailure } } log.Printf("%v: running with state: %v, index: %v", a.ID(), a.state, s.Index()) // Make some random length string data. data := NewDataMaker(a.conf.MsgSize, a.conf.MsgCount-a.state.SentMessages) defer data.Stop() r := ring.New(a.flow.NewContextualName("consumer"), a.conf.NrConsumers) start := time.Now() for { select { case <-a.exit: if _, err := s.Store(a.state); err != nil { log.Printf("%v: failed to save state: %v", a, err) } return Exit case <-a.chaos.C: if _, err := s.Store(a.state); err != nil { log.Printf("%v: failed to save state: %v", a, err) } return Failure case <-ticker.C: if err := a.started.Alive(); err != nil { return Failure } if _, err := s.Store(a.state); err != nil { return Failure } case <-data.Done(): if err := a.tx.Flush(); err != nil { return SendFailure } if err := a.tx.Send(a.flow.NewContextualName("leader"), &ResultMsg{Producer: a.ID(), Count: a.state.SentMessages, From: a.ID(), Duration: a.state.Duration}); err != nil { return SendFailure } if _, err := s.Store(a.state); err != nil { log.Printf("%v: failed to save state: %v", a, err) } return IndividualFinished case d := <-data.Next(): if a.state.SentMessages%100 == 0 { a.state.Duration += time.Now().Sub(start).Seconds() start = time.Now() } if a.state.SentMessages%10000 == 0 { if _, err := s.Store(a.state); err != nil { log.Printf("%v: failed to save state: %v", a, err) return Failure } } if err := a.tx.SendBuffered(r.ByInt(a.state.SentMessages), &DataMsg{Producer: a.ID(), Data: d}); err != nil { if _, err := s.Store(a.state); err != nil { log.Printf("%v: failed to save state: %v", a, err) } return SendFailure } a.state.SentMessages++ } } }