func (op *obcBatch) main() {
	for {
		select {
		case <-op.pbft.closed:
			close(op.idleChan)
			return
		case ocMsg := <-op.incomingChan:
			if err := op.processMessage(ocMsg.msg, ocMsg.sender); nil != err {
				logger.Error("Error processing message: %v", err)
			}
		case <-op.batchTimer.C:
			logger.Info("Replica %d batch timer expired", op.pbft.id)
			if op.pbft.activeView && (len(op.batchStore) > 0) {
				op.sendBatch()
			}
		case c := <-op.custodyTimerChan:
			// XXX filter out complaints that are about old requests

			if !c.complaint {
				logger.Warning("Batch replica %d custody expired, complaining: %s", op.pbft.id, c.hash)
				op.broadcastMsg(&BatchMessage{&BatchMessage_Complaint{c.req.(*Request)}})
			} else {
				if op.pbft.activeView {
					logger.Debug("Batch replica %d complaint timeout expired for %s", op.pbft.id, c.hash)
					op.pbft.sendViewChange()
				}
			}
		case execInfo := <-op.execChan:
			op.executeImpl(execInfo.seqNo, execInfo.raw)
		case op.idleChan <- struct{}{}:
			// Only used to detect thread idleness during unit tests
		}
	}
}
// allow the primary to send a batch when the timer expires
allow the primary to send a batch when the timer expires
// allow the primary to send a batch when the timer expires
func (op *obcBatch) main() {
	for {
		select {
		case <-op.pbft.closed:
			close(op.idleChan)
			return
		case ocMsg := <-op.incomingChan:
			if err := op.processMessage(ocMsg.msg, ocMsg.sender); nil != err {
				logger.Error("Error processing message: %v", err)
			}
		case <-op.batchTimer.C:
			logger.Info("Replica %d batch timer expired", op.pbft.id)
			if op.pbft.activeView && (len(op.batchStore) > 0) {
				op.sendBatch()
			}
		case c := <-op.custodyTimerChan:
			if !c.complaint {
				logger.Warning("Batch replica %d custody expired, complaining: %s", op.pbft.id, c.hash)
				op.broadcastMsg(&BatchMessage{&BatchMessage_Complaint{c.req.(*Request)}})
			} else {
				if op.pbft.activeView {
					logger.Debug("Batch replica %d complaint timeout expired for %s", op.pbft.id, c.hash)
					op.pbft.sendViewChange()
				}
			}
		case execInfo := <-op.execChan:
			op.executeImpl(execInfo.seqNo, execInfo.raw)
		case op.idleChan <- struct{}{}:
		}
	}
}
func ( op * obcBatch ) main ( ) { for { select { case <- op . pbft . closed : close ( op . idleChan ) return case ocMsg := <- op . incomingChan : if err := op . processMessage ( ocMsg . msg , ocMsg . sender ) ; nil != err { logger . Error ( " " , err ) } case <- op . batchTimer . C : logger . Info ( " " , op . pbft . id ) if op . pbft . activeView && ( len ( op . batchStore ) > 0 ) { op . sendBatch ( ) } case c := <- op . custodyTimerChan : if ! c . complaint { logger . Warning ( " " , op . pbft . id , c . hash ) op . broadcastMsg ( & BatchMessage { & BatchMessage_Complaint { c . req . ( * Request ) } } ) } else { if op . pbft . activeView { logger . Debug ( " " , op . pbft . id , c . hash ) op . pbft . sendViewChange ( ) } } case execInfo := <- op . execChan : op . executeImpl ( execInfo . seqNo , execInfo . raw ) case op . idleChan <- struct { } { } : } } }
allow the primary to send a batch when the timer expires
allow the primary to send a batch when the timer expires
// XXX filter out complaints that are about old requests // Only used to detect thread idleness during unit tests