Class: JRubyBridge::Service

Inherits:
Object
  • Object
show all
Defined in:
lib/jruby_bridge/service.rb

Overview

A Ruby-managed JRuby application.

Constant Summary collapse

DAEMON =

Path to JRuby application

File.join(File.dirname(__FILE__), 'server.rb')
PORT =

Port to listen on in JRuby

44344
TIMEOUT =

Time to allow JRuby to initialize, in 100-ms increments

300

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.default_uriObject



92
93
94
# File 'lib/jruby_bridge/service.rb', line 92

def self.default_uri
  "druby://localhost:#{PORT}"
end

.drb_start(port) ⇒ Object

Called by the server script in JRuby context



80
81
82
83
84
85
86
87
88
89
90
# File 'lib/jruby_bridge/service.rb', line 80

def self.drb_start(port)
  port ||= PORT

  DRb.start_service "druby://localhost:#{port.to_i}", self.new

  cls = self
  trap('HUP') { DRb.stop_service; cls.drb_start(port) }
  trap('INT') { puts 'Stopping jruby service'; DRb.stop_service }

  DRb.thread.join
end

.exec(port) ⇒ Object

Replace current process with JRuby running JRubyBridge::Service



68
69
70
71
72
73
74
75
76
77
# File 'lib/jruby_bridge/service.rb', line 68

def self.exec(port)
  jruby = get_jruby
  command = "#{jruby} #{DAEMON} #{port || ''}"
  puts "Running #{command}"
  Kernel.exec command if jruby

  # Note: a raised exception goes nowhere: instead use exit status
  $stderr.puts "No JRUBY found!"
  return 1
end

.get_jrubyObject

Return command to launch JRuby interpreter



97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/jruby_bridge/service.rb', line 97

def self.get_jruby
  # FIXME: this should detect RVM first and system second

  # 1. detect system JRuby
  jruby = `which jruby`
  return jruby.chomp if (! jruby.empty?)

  # 2. detect RVM-managed JRuby
  return nil if (`which rvm`).empty?
  jruby = `rvm list`.split("\n").select { |rb| rb.include? 'jruby' }.first
  return nil if (! jruby)

  "rvm #{jruby.strip.split(' ').first} do ruby "
end

.new_drb_objectObject



122
123
124
# File 'lib/jruby_bridge/service.rb', line 122

def self.new_drb_object
  DRb::DRbObject.new_with_uri(default_uri)
end

.service_send(method, *args) ⇒ Object

this will return a new DRuby connection



113
114
115
116
117
118
119
120
# File 'lib/jruby_bridge/service.rb', line 113

def self.service_send(method, *args)
  begin
    new_drb_object.tap { |obj| obj.send(method, *args) }
  rescue DRb::DRbConnError => e
    # $stderr.puts e.backtrace.join("\n")
    raise DRbConnectionError.new(e.message)
  end
end

.startObject

Raises:



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/jruby_bridge/service.rb', line 40

def self.start
  return @pid if @pid
  cls = self
  @pid = Process.fork do
    exit(cls.exec PORT)
  end
  # TODO : check child exit status and raise JRubyExecError
  Process.detach(@pid)

  connected = false
  TIMEOUT.times do
    begin
      DRb::DRbObject.new_with_uri(default_uri).to_s
      connected = true
      break
    rescue DRb::DRbConnError
      sleep 0.1
    end
  end
  raise DRbConnectionError.new("Could not connect to #{default_uri}") if \
        (! connected)
end

.stopObject



63
64
65
# File 'lib/jruby_bridge/service.rb', line 63

def self.stop
  service_send :stop
end

.with_service(&block) ⇒ Object



33
34
35
36
37
38
# File 'lib/jruby_bridge/service.rb', line 33

def self.with_service(&block)
  start
  yield
ensure
  stop
end

Instance Method Details

#proxy_new(klass, *args) ⇒ Object



25
26
27
# File 'lib/jruby_bridge/service.rb', line 25

def proxy_new(klass, *args)
  klass.new *args
end

#stopObject



29
30
31
# File 'lib/jruby_bridge/service.rb', line 29

def stop
  DRb.stop_service
end