Skip to content
Snippets Groups Projects
fsm_connect.go 1.17 KiB
Newer Older
Oliver Herms's avatar
Oliver Herms committed
package server

import (
	"fmt"
	"net"
	"time"
)

type connectState struct {
	fsm *FSM2
}

func newConnectState(fsm *FSM2) *connectState {
	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"
}