gamespy_query 0.2.0pre9 → 0.2.0pre10

Sign up to get free protection for your applications and to get access to all the features.
@@ -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