gamespy_query 0.2.0pre9 → 0.2.0pre10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -69,7 +69,7 @@ STR
69
69
  str
70
70
  end
71
71
 
72
- PLATFORM_IR = /-mswin32/
72
+ PLATFORM_IR = RUBY_PLATFORM =~ /-mswin32/
73
73
 
74
74
  # Float Regex
75
75
  RX_F = /\A\-?[0-9]+\.[0-9]*\Z/
@@ -128,8 +128,9 @@ module GamespyQuery
128
128
 
129
129
  run do |opts, args, cmd|
130
130
  opts = GamespyQuery::Options.setup_master_opts opts
131
- process = GamespyQuery::SocketMaster.process_master(opts[:game], opts[:geo])
132
- puts process
131
+ process = GamespyQuery::SocketMaster.process_master(opts[:game], opts[:geo], nil, false, true, true)
132
+ puts process.size
133
+ #puts process
133
134
  end
134
135
  end
135
136
 
@@ -11,8 +11,9 @@ module GamespyQuery
11
11
  class Socket < UDPSocket
12
12
  include Funcs
13
13
 
14
+
14
15
  # Default timeout per connection state
15
- DEFAULT_TIMEOUT = 3
16
+ DEFAULT_TIMEOUT = 4
16
17
 
17
18
  # Maximum amount of packets sent by the server
18
19
  # This is a limit set by gamespy
@@ -113,7 +114,7 @@ module GamespyQuery
113
114
 
114
115
  # Temp Workaround for IO.select issue on IR
115
116
  def _read_non_block
116
- if RUBY_PLATFORM =~ PLATFORM_IR
117
+ if PLATFORM_IR
117
118
  time_end = Time.now + DEFAULT_TIMEOUT
118
119
  success = false
119
120
  until success || Time.now >= time_end
@@ -222,7 +223,8 @@ module GamespyQuery
222
223
  end
223
224
 
224
225
  # Determine Read/Write/Exception state
225
- def handle_state; [STATE_INIT, STATE_RECEIVED_CHALLENGE].include? state; end
226
+ WRITE_STATES = [STATE_INIT, STATE_RECEIVED_CHALLENGE]
227
+ def handle_state; WRITE_STATES.include? state; end
226
228
 
227
229
  # Process data
228
230
  # Supports challenge/response and multi-packet
@@ -250,13 +252,13 @@ module GamespyQuery
250
252
  begin
251
253
  until valid? || failed
252
254
  if handle_state
253
- if RUBY_PLATFORM =~ PLATFORM_IR || IO.select(nil, [self], nil, DEFAULT_TIMEOUT)
255
+ if PLATFORM_IR || IO.select(nil, [self], nil, DEFAULT_TIMEOUT)
254
256
  handle_write
255
257
  else
256
258
  raise TimeOutError, "TimeOut during write, #{self}"
257
259
  end
258
260
  else
259
- if RUBY_PLATFORM =~ PLATFORM_IR || IO.select([self], nil, nil, DEFAULT_TIMEOUT)
261
+ if PLATFORM_IR || IO.select([self], nil, nil, DEFAULT_TIMEOUT)
260
262
  handle_read
261
263
  else
262
264
  raise TimeOutError, "TimeOut during read, #{self}"
@@ -8,6 +8,8 @@ module GamespyQuery
8
8
  # Default maximum concurrent connections
9
9
  DEFAULT_MAX_CONNECTIONS = 128
10
10
 
11
+ DEFAULT_THREADS = 0
12
+
11
13
  # Configurable timeout in seconds
12
14
  attr_accessor :timeout
13
15
 
@@ -16,33 +18,64 @@ module GamespyQuery
16
18
 
17
19
  # Initializes the object
18
20
  # @param [Array] addrs List of addresses to process
19
- def initialize addrs
21
+ def initialize addrs, info = false
20
22
  @addrs = addrs
23
+ @info = info
21
24
 
22
25
  @timeout, @max_connections = Socket::DEFAULT_TIMEOUT, DEFAULT_MAX_CONNECTIONS # Per select iteration
23
26
  end
24
27
 
25
28
  # Process the list of addresses
26
- def process!
29
+ def process! use_threads = DEFAULT_THREADS
27
30
  sockets = []
31
+ if use_threads.to_i > 0
32
+ monitor = Monitor.new # TODO...
33
+ threads = []
34
+ addrs_list = @addrs.each_slice(@addrs.size / use_threads).to_a
35
+ use_threads.times.each do |i|
36
+ list = addrs_list.shift
37
+ break if list.nil? || list.empty?
38
+ puts "Spawning thread #{i}" if @info
39
+
40
+ threads << Thread.new(list, i) do |addrs, id|
41
+ puts "Thread: #{id} Start, #{addrs.size}" if @info
42
+ out = proc(addrs, monitor)
43
+
44
+ puts "Thread: #{id} Pushing output to list. #{out.size}" if @info
45
+ monitor.synchronize do
46
+ sockets += out
47
+ end
48
+ puts "Thread: #{id} End" if @info
49
+ end
50
+ end
51
+ threads.each {|t| t.join}
52
+ else
53
+ sockets = proc @addrs
54
+ end
28
55
 
29
- until @addrs.empty?
30
- addrs = @addrs.shift @max_connections
31
- queue = addrs.map { |addr| Socket.new(addr) }
56
+ return sockets
57
+ end
58
+
59
+ def proc addrs_list
60
+ sockets = []
32
61
 
62
+ until addrs_list.empty?
63
+ addrs = addrs_list.shift @max_connections
64
+
65
+ queue = addrs.map { |addr| Socket.new(addr) }
33
66
  sockets += queue
34
67
 
35
68
  until queue.empty?
36
69
  # Fill up the Sockets pool until max_conn
37
- if FILL_UP_ON_SPACE && queue.size < @max_connections
38
- addrs = @addrs.shift (@max_connections - queue.size)
70
+ if FILL_UP_ON_SPACE && queue.size < @max_connections && !addrs_list.empty?
71
+ addrs = addrs_list.shift (@max_connections - queue.size)
39
72
  socks = addrs.map { |addr| Socket.new(addr) }
40
73
 
41
74
  queue += socks
42
75
  sockets += socks
43
76
  end
44
77
 
45
- write_sockets, read_sockets = queue.reject {|s| s.valid? }.partition {|s| s.handle_state }
78
+ write_sockets, read_sockets = queue.partition {|s| s.handle_state }
46
79
 
47
80
  unless ready = IO.select(read_sockets, write_sockets, nil, @timeout)
48
81
  Tools.logger.warn "Timeout, no usable sockets in current queue, within timeout period (#{@timeout}s)"
@@ -51,7 +84,7 @@ module GamespyQuery
51
84
  next
52
85
  end
53
86
 
54
- Tools.debug {"Sockets: #{queue.size}, AddrsLeft: #{@addrs.size}, ReadReady: #{"#{ready[0].size} / #{read_sockets.size}, WriteReady: #{ready[1].size} / #{write_sockets.size}, ExcReady: #{ready[2].size} / #{queue.size}" unless ready.nil?}"}
87
+ Tools.debug {"Sockets: #{queue.size}, AddrsLeft: #{addrs_list.size}, ReadReady: #{"#{ready[0].size} / #{read_sockets.size}, WriteReady: #{ready[1].size} / #{write_sockets.size}, ExcReady: #{ready[2].size} / #{queue.size}" unless ready.nil?}"}
55
88
 
56
89
  # Read
57
90
  ready[0].each { |s| begin; s.handle_read(); rescue nil, Exception => e; queue.delete(s); end }
@@ -61,10 +94,11 @@ module GamespyQuery
61
94
 
62
95
  # Exceptions
63
96
  #ready[2].each { |s| queue.delete(s) unless s.handle_exc }
97
+ queue.reject! {|s| s.valid? }
64
98
  end
65
99
  end
66
100
 
67
- return sockets
101
+ sockets
68
102
  end
69
103
 
70
104
  class <<self
@@ -73,7 +107,7 @@ module GamespyQuery
73
107
  # @param [String] game Game to fetch info from
74
108
  # @param [String] geo Geo location enabled?
75
109
  # @param [Array] remote Hostname and path+filename strings if the list needs to be fetched from http server
76
- def process_master(game = "arma2oapc", geo = nil, remote = nil, dedicated_only = false, sm_dedicated_only = true)
110
+ def process_master(game = "arma2oapc", geo = nil, remote = nil, dedicated_only = false, sm_dedicated_only = true, info = false)
77
111
  master = GamespyQuery::Master.new(geo, game)
78
112
  list = if remote
79
113
  Net::HTTP.start(remote[0]) do |http|
@@ -98,9 +132,11 @@ module GamespyQuery
98
132
  dat
99
133
  end
100
134
 
101
- sm = GamespyQuery::SocketMaster.new(gm_dat.keys)
135
+ sm = GamespyQuery::SocketMaster.new(gm_dat.keys, info)
102
136
  sockets = sm.process!
103
- sockets.select{|s| s.valid? }.each do |s|
137
+ valid_sockets = sockets.select{|s| s.valid? }
138
+ puts "Sockets: #{sockets.size}, Valid: #{valid_sockets.size}" if info
139
+ valid_sockets.each do |s|
104
140
  begin
105
141
  data = gm_dat[s.addr]
106
142
  data[:ip], data[:port] = s.addr.split(":")
@@ -1,4 +1,4 @@
1
1
  module GamespyQuery
2
2
  # Version of the library
3
- VERSION = "0.2.0pre9"
3
+ VERSION = "0.2.0pre10"
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gamespy_query
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0pre9
4
+ version: 0.2.0pre10
5
5
  prerelease: 5
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-11 00:00:00.000000000 Z
12
+ date: 2012-05-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cri