specjour 0.1.12 → 0.1.13

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.
data/README.markdown CHANGED
@@ -1,4 +1,7 @@
1
1
  # Specjour
2
+
3
+ ## FUCK SETI. Run specs with your spare CPU cycles.
4
+
2
5
  _Distribute your spec suite amongst your LAN via Bonjour._
3
6
 
4
7
  1. Spin up a manager on each machine that can run your specs.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.12
1
+ 0.1.13
data/bin/specjour CHANGED
@@ -23,6 +23,10 @@ optparse = OptionParser.new do |opts|
23
23
  options[:worker_args] = args[0], args[1], args[2]
24
24
  end
25
25
 
26
+ opts.on('--log', TrueClass, 'print debug messages to stdout') do |val|
27
+ Specjour.new_logger Logger::DEBUG
28
+ end
29
+
26
30
  opts.on_tail('-v', '--version', 'Show the version of specjour') do
27
31
  abort Specjour::VERSION
28
32
  end
@@ -1,18 +1,15 @@
1
1
  module Specjour
2
2
  class Connection
3
- MAX_RECONNECTS = 5
4
-
5
3
  include Protocol
6
4
  extend Forwardable
7
5
 
8
6
  attr_reader :uri
9
7
  attr_writer :socket
10
- attr_accessor :reconnection_attempts
11
8
 
12
9
  def_delegators :socket, :flush, :closed?, :close, :gets, :each
13
10
 
14
11
  def self.wrap(established_connection)
15
- host, port = established_connection.peeraddr.values_at(2,1)
12
+ host, port = established_connection.peeraddr.values_at(3,1)
16
13
  connection = new URI::Generic.build(:host => host, :port => port)
17
14
  connection.socket = established_connection
18
15
  connection
@@ -20,23 +17,25 @@ module Specjour
20
17
 
21
18
  def initialize(uri)
22
19
  @uri = uri
23
- @reconnection_attempts = 0
24
20
  end
25
21
 
26
22
  def connect
27
- @socket = TCPSocket.open(uri.host, uri.port)
28
- rescue SystemCallError => error
29
- Kernel.puts "Could not connect to #{uri.to_s}\n#{error.inspect}"
23
+ timeout { connect_socket }
30
24
  end
31
25
 
32
26
  def socket
33
27
  @socket ||= connect
34
28
  end
35
29
 
30
+ def timeout(&block)
31
+ Timeout.timeout(5, &block)
32
+ rescue Timeout::Error
33
+ raise Error, "Connection to dispatcher timed out"
34
+ end
35
+
36
36
  def print(arg)
37
37
  socket.print dump_object(arg)
38
38
  rescue SystemCallError => error
39
- Kernel.p error
40
39
  reconnect
41
40
  retry
42
41
  end
@@ -52,14 +51,16 @@ module Specjour
52
51
 
53
52
  protected
54
53
 
54
+ def connect_socket
55
+ @socket = TCPSocket.open(uri.host, uri.port)
56
+ rescue Errno::ECONNREFUSED => error
57
+ Specjour.logger.debug "Could not connect to #{uri.to_s}\n#{error.inspect}"
58
+ retry
59
+ end
60
+
55
61
  def reconnect
56
- socket.close
57
- if reconnection_attempts < MAX_RECONNECTS
58
- connect
59
- self.reconnection_attempts += 1
60
- else
61
- raise Error, "Lost connection #{MAX_RECONNECTS} times"
62
- end
62
+ socket.close unless socket.closed?
63
+ connect
63
64
  end
64
65
  end
65
66
  end
@@ -40,12 +40,16 @@ module Specjour
40
40
  end
41
41
 
42
42
  def fetch_manager(uri)
43
- manager = DRbObject.new_with_uri(uri.to_s)
44
- if !managers.include?(manager) && manager.available_for?(project_name)
45
- set_up_manager(manager, uri)
46
- managers << manager
47
- self.worker_size += manager.worker_size
43
+ Timeout.timeout(1) do
44
+ manager = DRbObject.new_with_uri(uri.to_s)
45
+ if !managers.include?(manager) && manager.available_for?(project_name)
46
+ set_up_manager(manager, uri)
47
+ managers << manager
48
+ self.worker_size += manager.worker_size
49
+ end
48
50
  end
51
+ rescue Timeout::Error
52
+ Specjour.logger.debug "Couldn't work with manager at #{uri}"
49
53
  end
50
54
 
51
55
  def gather_managers
@@ -53,7 +57,7 @@ module Specjour
53
57
  Signal.trap('INT') { exit }
54
58
  browser = DNSSD::Service.new
55
59
  begin
56
- Timeout.timeout(5) do
60
+ Timeout.timeout(10) do
57
61
  browser.browse '_druby._tcp' do |reply|
58
62
  if reply.flags.add?
59
63
  resolve_reply(reply)
@@ -73,6 +77,10 @@ module Specjour
73
77
  @hostname ||= Socket.gethostname
74
78
  end
75
79
 
80
+ def host_ip
81
+ @host_ip ||= Specjour.ip_from_hostname hostname
82
+ end
83
+
76
84
  def printer
77
85
  @printer ||= begin
78
86
  p = Printer.new
@@ -91,7 +99,8 @@ module Specjour
91
99
 
92
100
  def resolve_reply(reply)
93
101
  DNSSD.resolve!(reply) do |resolved|
94
- uri = URI::Generic.build :scheme => reply.service_name, :host => resolved.target, :port => resolved.port
102
+ resolved_ip = Specjour.ip_from_hostname(resolved.target)
103
+ uri = URI::Generic.build :scheme => reply.service_name, :host => resolved_ip, :port => resolved.port
95
104
  fetch_manager(uri)
96
105
  resolved.service.stop if resolved.service.started?
97
106
  end
@@ -103,7 +112,7 @@ module Specjour
103
112
 
104
113
  def set_up_manager(manager, uri)
105
114
  manager.project_name = project_name
106
- manager.dispatcher_uri = URI::Generic.build :scheme => "specjour", :host => hostname, :port => printer.port
115
+ manager.dispatcher_uri = URI::Generic.build :scheme => "specjour", :host => host_ip, :port => printer.port
107
116
  at_exit { manager.kill_worker_processes }
108
117
  end
109
118
 
@@ -44,7 +44,7 @@ module Specjour
44
44
  def dispatch_workers
45
45
  (1..worker_size).each do |index|
46
46
  worker_pids << fork do
47
- exec("specjour --batch-size #{batch_size} --do-work #{project_path},#{dispatcher_uri},#{index}")
47
+ exec("specjour --batch-size #{batch_size} #{'--log' if Specjour.log?} --do-work #{project_path},#{dispatcher_uri},#{index}")
48
48
  Kernel.exit!
49
49
  end
50
50
  end
data/lib/specjour.rb CHANGED
@@ -9,6 +9,8 @@ autoload :Forwardable, 'forwardable'
9
9
  autoload :GServer, 'gserver'
10
10
  autoload :Timeout, 'timeout'
11
11
  autoload :Benchmark, 'benchmark'
12
+ autoload :Logger, 'logger'
13
+ autoload :Socket, 'socket'
12
14
 
13
15
  module Specjour
14
16
  autoload :Connection, 'specjour/connection'
@@ -21,6 +23,25 @@ module Specjour
21
23
  autoload :RsyncDaemon, 'specjour/rsync_daemon'
22
24
  autoload :Worker, 'specjour/worker'
23
25
 
24
- VERSION = "0.1.12".freeze
26
+ VERSION = "0.1.13".freeze
27
+
25
28
  class Error < StandardError; end
29
+
30
+ def self.logger
31
+ @logger ||= new_logger
32
+ end
33
+
34
+ def self.new_logger(level = Logger::UNKNOWN)
35
+ @logger = Logger.new $stdout
36
+ @logger.level = level
37
+ @logger
38
+ end
39
+
40
+ def self.log?
41
+ logger.level != Logger::UNKNOWN
42
+ end
43
+
44
+ def self.ip_from_hostname(hostname)
45
+ Socket.getaddrinfo(hostname, nil).last.fetch(3)
46
+ end
26
47
  end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Specjour::Connection do
4
+ require 'stringio'
5
+ describe "#print" do
6
+ context "connection unavailable" do
7
+ let(:connection) do
8
+ Specjour::Connection.new(URI.parse("specjour://me.local:12345"))
9
+ end
10
+
11
+ it "reconnects" do
12
+ socket = mock(:closed? => false, :close => true)
13
+ socket.stub(:print).and_raise(Errno::EPIPE)
14
+ connection.instance_variable_set(:@socket, socket)
15
+ new_socket = mock(:print => true)
16
+ TCPSocket.stub(:open => new_socket)
17
+ connection.print('hi').should be_true
18
+ end
19
+ end
20
+ end
21
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 12
9
- version: 0.1.12
8
+ - 13
9
+ version: 0.1.13
10
10
  platform: ruby
11
11
  authors:
12
12
  - Sandro Turriate
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-06 00:00:00 -04:00
17
+ date: 2010-04-14 00:00:00 -04:00
18
18
  default_executable: specjour
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -140,6 +140,7 @@ signing_key:
140
140
  specification_version: 3
141
141
  summary: Distribute your spec suite amongst your LAN via Bonjour.
142
142
  test_files:
143
+ - spec/lib/specjour/connection_spec.rb
143
144
  - spec/lib/specjour/core_ext/array_spec.rb
144
145
  - spec/lib/specjour/worker_spec.rb
145
146
  - spec/spec_helper.rb