Skip to content
Snippets Groups Projects
fsm_active.go 1.4 KiB
Newer Older
  • Learn to ignore specific revisions
  • Oliver Herms's avatar
    Oliver Herms committed
    package server
    
    
    Oliver Herms's avatar
    Oliver Herms committed
    import (
    	"fmt"
    	"net"
    	"time"
    )
    
    
    Oliver Herms's avatar
    Oliver Herms committed
    type activeState struct {
    
    Oliver Herms's avatar
    Oliver Herms committed
    	fsm *FSM
    
    Oliver Herms's avatar
    Oliver Herms committed
    }
    
    
    Oliver Herms's avatar
    Oliver Herms committed
    func newActiveState(fsm *FSM) *activeState {
    
    Oliver Herms's avatar
    Oliver Herms committed
    	return &activeState{
    		fsm: fsm,
    	}
    }
    
    
    Oliver Herms's avatar
    Oliver Herms committed
    func (s activeState) run() (state, string) {
    
    Oliver Herms's avatar
    Oliver Herms committed
    	for {
    		select {
    		case e := <-s.fsm.eventCh:
    
    Oliver Herms's avatar
    Oliver Herms committed
    			switch e {
    			case ManualStop:
    				return s.manualStop()
    			case Cease:
    				return s.cease()
    			default:
    				continue
    
    Oliver Herms's avatar
    Oliver Herms committed
    			}
    		case <-s.fsm.connectRetryTimer.C:
    
    Oliver Herms's avatar
    Oliver Herms committed
    			return s.connectRetryTimerExpired()
    
    Oliver Herms's avatar
    Oliver Herms committed
    		case c := <-s.fsm.conCh:
    
    Oliver Herms's avatar
    Oliver Herms committed
    			return s.connectionSuccess(c)
    
    Oliver Herms's avatar
    Oliver Herms committed
    		}
    	}
    }
    
    Oliver Herms's avatar
    Oliver Herms committed
    
    func (s *activeState) manualStop() (state, string) {
    	s.fsm.con.Close()
    	s.fsm.resetConnectRetryCounter()
    	stopTimer(s.fsm.connectRetryTimer)
    	return newIdleState(s.fsm), "Manual stop event"
    }
    
    func (s *activeState) cease() (state, string) {
    	s.fsm.con.Close()
    	return newCeaseState(), "Cease"
    }
    
    func (s *activeState) connectRetryTimerExpired() (state, string) {
    	s.fsm.resetConnectRetryTimer()
    	s.fsm.tcpConnect()
    	return newConnectState(s.fsm), "Connect retry timer expired"
    }
    
    func (s *activeState) connectionSuccess(con net.Conn) (state, string) {
    	s.fsm.con = con
    	stopTimer(s.fsm.connectRetryTimer)
    	err := s.fsm.sendOpen()
    	if err != nil {
    		s.fsm.resetConnectRetryTimer()
    		s.fsm.connectRetryCounter++
    		return newIdleState(s.fsm), fmt.Sprintf("Sending OPEN message failed: %v", err)
    	}
    	s.fsm.holdTimer = time.NewTimer(time.Minute * 4)
    	return newOpenSentState(s.fsm), "Sent OPEN message"
    }