Skip to content
Snippets Groups Projects
fsm_connect.go 1.17 KiB
Newer Older
  • Learn to ignore specific revisions
  • Oliver Herms's avatar
    Oliver Herms committed
    package server
    
    import (
    	"fmt"
    	"net"
    	"time"
    )
    
    type connectState 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 newConnectState(fsm *FSM) *connectState {
    
    Oliver Herms's avatar
    Oliver Herms committed
    	return &connectState{
    		fsm: fsm,
    	}
    }
    
    
    Oliver Herms's avatar
    Oliver Herms committed
    func (s connectState) 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:
    
    Oliver Herms's avatar
    Oliver Herms committed
    				return s.manualStop()
    
    Oliver Herms's avatar
    Oliver Herms committed
    			case Cease:
    				return newCeaseState(), "Cease"
    			default:
    				continue
    
    Oliver Herms's avatar
    Oliver Herms committed
    			}
    		case <-s.fsm.connectRetryTimer.C:
    			s.connectRetryTimerExpired()
    			continue
    		case c := <-s.fsm.conCh:
    
    Oliver Herms's avatar
    Oliver Herms committed
    			return s.connectionSuccess(c)
    
    Oliver Herms's avatar
    Oliver Herms committed
    		}
    	}
    }
    
    func (s *connectState) connectionSuccess(c net.Conn) (state, string) {
    	s.fsm.con = c
    	stopTimer(s.fsm.connectRetryTimer)
    	err := s.fsm.sendOpen()
    	if err != nil {
    		return newIdleState(s.fsm), fmt.Sprintf("Unable to send open: %v", err)
    	}
    	s.fsm.holdTimer = time.NewTimer(time.Minute * 4)
    	return newOpenSentState(s.fsm), "TCP connection succeeded"
    }
    
    func (s *connectState) connectRetryTimerExpired() {
    	s.fsm.resetConnectRetryTimer()
    	s.fsm.tcpConnect()
    }
    
    func (s *connectState) manualStop() (state, string) {
    	s.fsm.resetConnectRetryCounter()
    	stopTimer(s.fsm.connectRetryTimer)
    	return newIdleState(s.fsm), "Manual stop event"
    }