Class: Tkellem::IrcServerConnection::ConnectionState

Inherits:
Struct
  • Object
show all
Defined in:
lib/tkellem/irc_server.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bouncer, network) ⇒ ConnectionState

Returns a new instance of ConnectionState.



63
64
65
66
# File 'lib/tkellem/irc_server.rb', line 63

def initialize(bouncer, network)
  super(bouncer, network, Set.new, false)
  reset
end

Instance Attribute Details

#attemptedObject

Returns the value of attribute attempted

Returns:

  • (Object)

    the current value of attempted



62
63
64
# File 'lib/tkellem/irc_server.rb', line 62

def attempted
  @attempted
end

#bouncerObject

Returns the value of attribute bouncer

Returns:

  • (Object)

    the current value of bouncer



62
63
64
# File 'lib/tkellem/irc_server.rb', line 62

def bouncer
  @bouncer
end

#gettingObject

Returns the value of attribute getting

Returns:

  • (Object)

    the current value of getting



62
63
64
# File 'lib/tkellem/irc_server.rb', line 62

def getting
  @getting
end

#networkObject

Returns the value of attribute network

Returns:

  • (Object)

    the current value of network



62
63
64
# File 'lib/tkellem/irc_server.rb', line 62

def network
  @network
end

Instance Method Details

#connect!Object



68
69
70
71
72
73
74
# File 'lib/tkellem/irc_server.rb', line 68

def connect!
  raise("already in the process of getting an address") if getting
  self.getting = true
  network.reload
  host_infos = network.hosts.map { |h| h.attributes }
  EM.defer(proc { find_address(host_infos) }, method(:got_address))
end

#find_address(hosts) ⇒ Object

runs in threadpool



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/tkellem/irc_server.rb', line 81

def find_address(hosts)
  candidates = Set.new
  hosts.each do |host|
    Socket.getaddrinfo(host['address'], host['port'], Socket::AF_INET, Socket::SOCK_STREAM, Socket::IPPROTO_TCP).each do |found|
      candidates << [found[3], host['port'], host['ssl']]
    end
  end

  to_try = candidates.to_a.sort_by { rand }.find { |c| !attempted.include?(c) }
  if to_try.nil?
    # we've tried all possible hosts, start over
    return nil
  end

  return to_try
end

#got_address(to_try) ⇒ Object

back on event thread



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/tkellem/irc_server.rb', line 99

def got_address(to_try)
  self.getting = false

  if !to_try
    # sleep for a bit and try again
    bouncer.debug "All available addresses failed, sleeping 5s and then trying over"
    reset
    EM.add_timer(5) { connect! }
    return
  end

  attempted << to_try
  address, port, ssl = to_try

  bouncer.debug "Connecting to: #{Host.address_string(address, port, ssl)}"
  bouncer.failsafe("connect: #{Host.address_string(address, port, ssl)}") do
    EM.connect(address, port, IrcServerConnection, self, bouncer, ssl)
  end
end

#resetObject



76
77
78
# File 'lib/tkellem/irc_server.rb', line 76

def reset
  self.attempted.clear
end