fastest_server 0.1.0 → 0.1.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d73692c989e6f043a3b8d8d0a68597843684a2747cb0e71adf69731b2b239880
4
- data.tar.gz: 4760926c9ca2767644b02d3c91163ac8ea1777b69fc6d70cd6f31840e7286990
3
+ metadata.gz: 5f2becc475d385131ac09de21030cecc44930564099c8d9726c12ff2bf260007
4
+ data.tar.gz: c745479bb721293f55404979dc974e47ec0ffd1e9288bbed77e47d48f243ff67
5
5
  SHA512:
6
- metadata.gz: 4515eade6c6f41595ef446f5a8dcc3eb1688653eb1f72f3dfe6f673c53315ddfb3c986a1935ba1fd71b0eb39813055ac777c3f872a5f116151dac8649fa680b2
7
- data.tar.gz: adf14907807ee4daf93c8b05c44ec36847182c2cba21b8fec87f21077efe6e316234435d3bd6166da1c553fa88551b0ccd85b1737eea207836af4b7452cb5be3
6
+ metadata.gz: 0ec4a0a1217a34503cd447ab470aaabfcf2ef73f0c2e618fca4f08500e870e1a6d80563660f4b362ca6090ac96b789d51840befb114112252c297f09d8e1b5bc
7
+ data.tar.gz: 9a3f862977314eaecf3c6d8742611b65db49d59883e20b778b1db8022dce794e0da91c5c9a14cd92899209a8aaa60a18c1f6b8c32d1bcc1b0c0a891f074fb75e
data/.gitignore CHANGED
@@ -1,3 +1,5 @@
1
+ .DS_Store
2
+
1
3
  /.bundle/
2
4
  /.yardoc
3
5
  /_yardoc/
@@ -7,6 +9,7 @@
7
9
  /spec/reports/
8
10
  /tmp/
9
11
 
12
+ Gemfile.lock
10
13
  *.gem
11
14
 
12
15
  # rspec failure tracking
data/README.md CHANGED
@@ -8,7 +8,7 @@ Find the fastest server via ping.
8
8
 
9
9
  ## Usage
10
10
 
11
- The most basic usage is very simple, you may type `fastest` with a sequence of servers:
11
+ The most basic usage is very simple, you may type `fastest` with a sequence of servers[1]:
12
12
 
13
13
  $ fastest 5.153.63.162 159.8.223.72 169.38.84.49 169.46.49.132 23.246.195.8
14
14
  (after a while)
@@ -30,6 +30,11 @@ server will be displayed on the screen.
30
30
 
31
31
  Noticed that, you can also provide additional servers as parameters, even a `-f` or `--file` option has been set.
32
32
 
33
+ ## Disclaim
34
+
35
+ [1] The ip address all come from [lifesize](https://www.lifesize.com/en/app-help/admin/get-started/ip-address-list)
36
+ for test purpose only.
37
+
33
38
  ## Contributing
34
39
 
35
40
  Bug reports and pull requests are welcome on GitHub at https://github.com/DeathKing/fastest_server.
data/Rakefile CHANGED
@@ -6,5 +6,5 @@ RSpec::Core::RakeTask.new(:spec)
6
6
  task :default => :spec
7
7
 
8
8
  task :console do
9
- exec "irb -r mygem -I ./lib"
10
- end
9
+ exec "irb -r fastest_server -I ./lib"
10
+ end
@@ -22,5 +22,5 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency "bundler", "~> 1.16"
23
23
  spec.add_development_dependency "rake", "~> 10.0"
24
24
  spec.add_development_dependency "rspec", "~> 3.0"
25
- spec.add_development_dependency "clamp", "~> 1.0"
25
+ spec.add_dependency "clamp", "~> 1.0"
26
26
  end
@@ -1,7 +1,7 @@
1
1
  module FastestServer
2
2
  class Fastest
3
3
  def initialize(targets, max, verbose)
4
- @max = max
4
+ @max = [max, targets.size].min
5
5
  @jobs = targets
6
6
  @verbose = verbose
7
7
  @checkbook = {}
@@ -9,7 +9,7 @@ module FastestServer
9
9
 
10
10
  def formatted!
11
11
  return @formatted if @formatted
12
- header = header_format % ["Site", "IP", "Average", "Stddev", "Loss"]
12
+ header = header_format % ["Site", "IP", "Average", "Stddev", "Loss", "Status"]
13
13
  rows = [header, "-" * header.length]
14
14
  rows += @stats.map {|stat| format_row(stat)}
15
15
  @formatted = rows.join("\n")
@@ -18,7 +18,7 @@ module FastestServer
18
18
  def display!(verbose)
19
19
  sort!
20
20
  puts formatted! if verbose
21
- puts @stats.first[:target]
21
+ puts @stats.first[:server]
22
22
  end
23
23
 
24
24
  private
@@ -46,19 +46,16 @@ module FastestServer
46
46
  end
47
47
 
48
48
  def header_format
49
- "%#{@site_max_width}s %-16s%8s %6s %6s"
49
+ "%#{@site_max_width}s %-16s%8s %6s %6s %6s"
50
50
  end
51
51
 
52
52
  def row_format
53
- "%#{@site_max_width}s %16s %8.2f %6.2f %6.2f%s"
53
+ "%#{@site_max_width}s %16s %8.2f %6.2f %6.2f%s %6d"
54
54
  end
55
55
 
56
56
  def format_row stat
57
- row_format % [stat[:site], format_ip(stat[:ip]), stat[:avg], stat[:stddev], stat[:loss], '%']
58
- end
59
-
60
- def format_ip ip
61
- "%-3d.%-3d.%-3d.%-3d" % ip.split(".")
57
+ row_format % [stat[:site], stat[:ip], stat[:avg],
58
+ stat[:stddev], stat[:loss], '%', stat[:status]]
62
59
  end
63
60
 
64
61
  end
@@ -16,13 +16,11 @@ module FastestServer
16
16
  private
17
17
 
18
18
  def get_pinger
19
- @pinger ||= if (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM)
20
- WindowsPing
21
- elsif (/darwin/ =~ RUBY_PLATFORM)
22
- UnixPing
23
- elsif
24
- LinuxPing
25
- end
19
+ if (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM)
20
+ WindowsPing
21
+ else
22
+ LinuxPing
23
+ end
26
24
  end
27
25
  end
28
26
 
@@ -30,53 +28,79 @@ module FastestServer
30
28
  @server = server
31
29
  end
32
30
 
31
+ def execute_ping_command
32
+ raise NotImplementedError, "Subclass must implement execute_ping_command method."
33
+ end
34
+
35
+ # ping and parse the result
33
36
  def perform
34
- raise NotImplementedError
37
+ result, status = execute_ping_command
38
+
39
+ # we only process `successful` ping.
40
+ return parsed(status: status) unless status == 0
41
+
42
+ _, site, ip, _ = result.match(regex_ping)[0].split(" ")
43
+ ip.gsub!(regex_filter, "")
44
+ loss = result.match(regex_loss) ? $&.to_f : 100
45
+
46
+ if stat = result.match(regex_stat)
47
+ parsed(ip: ip, site: site, loss: loss,
48
+ max: stat["max"].to_f, min: stat["min"].to_f,
49
+ avg: stat["avg"].to_f, stddev: stat["stddev"]&.to_f || 0.0)
50
+ else
51
+ parsed(ip: ip, site: site, loss: loss, status: status)
52
+ end
53
+ end
54
+
55
+ def method_missing(name, *args)
56
+ if name =~ /regex_/
57
+ self.class.const_get(name.upcase)
58
+ else
59
+ super
60
+ end
35
61
  end
36
62
 
63
+ # From MacOX `ping` manual
64
+ #
65
+ # EXIT STATUS
66
+ # The `ping` utility exits with one of the following values:
67
+ # 0 At least one response was heard from the specified host
68
+ #
69
+ # 2 The transmission was successful but no responses were received.
70
+ #
71
+ # any other value
72
+ # An error occurred. These values are defined in <sysexists.h>
73
+ #
74
+ def parsed(**arguments)
75
+ {ip: @server, server: @server, site: @server, status: 0,
76
+ loss: 100, max: 0.0, min: 0.0, avg: 0.0, stddev: 0.0}.merge(arguments)
77
+ end
37
78
  end
38
79
 
39
80
  class WindowsPing < Ping
81
+ REGEX_PING = /Pinging.*/
82
+ REGEX_FILTER = /\[|\]/
83
+ REGEX_LOSS = /\(\d*% loss\)/
84
+ REGEX_STAT = /Minimum = (?<min>\d+)ms, Maximum = (?<max>\d+)ms, Average = (?<avg>\d+)ms(?<stddev>)/
85
+
86
+ def execute_ping_command
87
+ result = `chcp 437 && ping -n #{Ping.get_count} #@server`
88
+ status = $?
89
+ [result, $?]
90
+ end
40
91
  end
41
92
 
42
- class UnixPing < Ping
93
+ class LinuxPing < Ping
43
94
 
44
95
  REGEX_PING = /PING.*/
45
96
  REGEX_FILTER = /\(|\)|:/
46
- REGEX_LOSS = /(\d*.\d*)% packet loss/
97
+ REGEX_LOSS = /(?<loss>\d*)% packet loss/
47
98
  REGEX_STAT = /(?<min>\d*.\d*)\/(?<avg>\d*.\d*)\/(?<max>\d*.\d*)\/(?<stddev>\d*.\d*) ms/
48
99
 
49
- # ping and parse the result
50
- def perform
51
- #FIXME: may not thread safe
100
+ def execute_ping_command
52
101
  result = `ping -c #{Ping.get_count} -q #@server`
53
102
  status = $?
54
-
55
- # if we cannot find a valid information line, just return nil
56
- return useless_server unless result.match(REGEX_PING)
57
- _, site, ip, _ = $&.split(" ")
58
- ip.gsub!(REGEX_FILTER, "")
59
-
60
- base = useless_server(status)
61
-
62
- return base.merge(ip: ip) unless status == 0
63
-
64
- stat = result.match(REGEX_STAT)
65
- return base.merge({
66
- ip: ip,
67
- site: site,
68
- loss: result.match(REGEX_LOSS)[0].to_f,
69
- max: stat["max"].to_f,
70
- min: stat["min"].to_f,
71
- avg: stat["avg"].to_f,
72
- stddev: stat["stddev"].to_f})
73
- end
74
-
75
- private
76
-
77
- def useless_server(status=-1)
78
- {site: @server, ip: @server, target: @server, status: status,
79
- loss: 100, max: 0, min: 0, avg: 0, stddev: 0 }
103
+ [result, $?]
80
104
  end
81
105
  end
82
106
  end
@@ -1,3 +1,3 @@
1
1
  module FastestServer
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastest_server
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - DeathKing
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-22 00:00:00.000000000 Z
11
+ date: 2019-03-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -59,7 +59,7 @@ dependencies:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: '1.0'
62
- type: :development
62
+ type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
@@ -111,8 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
111
  - !ruby/object:Gem::Version
112
112
  version: '0'
113
113
  requirements: []
114
- rubyforge_project:
115
- rubygems_version: 2.7.6
114
+ rubygems_version: 3.0.3
116
115
  signing_key:
117
116
  specification_version: 4
118
117
  summary: Find the fastest server via ping.