Class: SPing::SessionManager

Inherits:
Object
  • Object
show all
Defined in:
lib/session_manager.rb

Overview

Container, which contains a collection of sessions and manages them.

Instance Method Summary collapse

Constructor Details

#initialize(host = '::', port = 6924) ⇒ SessionManager

Creates a new Session Manager, which can (and will) manage a number of sessions.

Parameters:

  • host (#to_s) (defaults to: '::')

    Host to which messages are to be bound and from which messages are sent accordingly.

  • port (#to_i) (defaults to: 6924)

    Port



18
19
20
21
22
23
24
25
26
27
# File 'lib/session_manager.rb', line 18

def initialize(host = '::', port = 6924)
  @host = host.to_s
  @port = port.to_i

  @sessions = {}
  @sessions_mutex = Mutex.new

  @socket = UDPSocket.new(Socket::AF_INET6)
  @socket.bind @host, @port
end

Instance Method Details

#del_session(session_id) ⇒ Object

Stops all threads connected to a session ID and removes the session from the Session Manager administration.

Parameters:

  • session_id (Integer)

    Session ID of the session to be removed.



62
63
64
65
66
67
68
69
# File 'lib/session_manager.rb', line 62

def del_session(session_id)
  $logger.debug "Delete session with session id #{session_id}"

  @sessions_mutex.synchronize do
    @sessions[session_id].stop
    @sessions.delete(session_id)
  end
end

#joinObject

Waits and blocks until the Session Manager is no longer running.



79
80
81
82
83
# File 'lib/session_manager.rb', line 79

def join
  @runner&.join
  @gc_thread&.join
  @server_thread&.join
end

#new_session(host, port = 6924) ⇒ Object

Initiates a new session with a peer.

Parameters:

  • host (#to_s)
  • port (#to_s, #to_i) (defaults to: 6924)


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/session_manager.rb', line 32

def new_session(host, port = 6924)
  $logger.info "Add new session for host #{host} port #{port}."
  session = SPing::Session.new host.to_s, port.to_i, @socket, true

  counter = 0
  loop do
    session_id = request_session session
    break if session_id

    # rubocop:disable Style/IfUnlessModifier
    if counter > 5
      raise OutOfSessions, 'The peer could not name a session ID that had not yet been assigned.'
    end
    # rubocop:enable Style/IfUnlessModifier

    counter += 1
  end

  $logger.info "TCP handshake for host #{host} port #{port} successful. Session ID is #{session.session_id}."

  $logger.info "Perform UDP handshake for session ID #{session.session_id}."
  session.start_udp_handshake_sender
rescue Errno::ECONNRESET, EOFError, IO::TimeoutError, SocketError, TCPHandshakeError => e
  $logger.warn "TCP handshake failed: #{e.message}"
rescue OutOfSessions => e
  $logger.error "Out of session: #{e.message}"
end

#runObject

Starts the Session Manager.



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/session_manager.rb', line 86

def run
  raise 'Client is already running.' if @runner
  raise 'GC is already running.' if @gc

  @runner = Thread.new do
    loop do
      Thread.new(@socket.recvfrom(10_000)) do |buf|
        handle_packet buf
      end
    end
  end
  @gc_thread = Thread.new do
    loop do
      do_gc
      sleep 10
    end
  end
end

#run_serverObject

Starts the server functionality of the Session Manager.



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/session_manager.rb', line 106

def run_server
  raise 'Server is already running.' if @server_thread
  raise 'Server already exist.' if @server

  @server = TCPServer.new @host, @port

  @server_thread = Thread.new do
    loop do
      Thread.new(@server.accept) do |client|
        handle_client client
      end
    end
  end

  return @server_thread
end

#stopObject

Stops the Session Manager. The server functionality must be stopped separately.



137
138
139
140
141
142
143
144
145
146
147
# File 'lib/session_manager.rb', line 137

def stop
  raise 'Session manager is not running.' unless @runner

  @runner.kill
  @runner = nil

  raise 'Session GC is not running.' unless @gc_thread

  @gc_thread.kill
  @gc_thread = nil
end

#stop_serverObject

Stops the server functionality of the Session Manager.



124
125
126
127
128
129
130
131
132
133
134
# File 'lib/session_manager.rb', line 124

def stop_server
  raise 'Server thread is not running.' unless @server_thread

  @server_thread.kill
  @server_thread = nil

  raise 'Server is not running.' unless @server

  @server.close
  @server = nil
end

#stop_sessionsObject

Stops all sessions or the threads that are connected to them.



72
73
74
75
76
# File 'lib/session_manager.rb', line 72

def stop_sessions
  @sessions.each do |_session_id, session|
    session.stop
  end
end