jruby_bridge 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +71 -0
- data/Rakefile +1 -0
- data/jruby_bridge.gemspec +23 -0
- data/lib/jruby_bridge.rb +6 -0
- data/lib/jruby_bridge/object_proxy.rb +23 -0
- data/lib/jruby_bridge/server.rb +8 -0
- data/lib/jruby_bridge/service.rb +127 -0
- data/lib/jruby_bridge/version.rb +3 -0
- metadata +86 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5367f5e9bf3e3c2bedc9a87cf8a4aca9689a2b8a
|
4
|
+
data.tar.gz: 9180d4e1e93394da2f89b0b3425b1fe0c6ee412a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: efa6be4f5888e1ab81e64c28820a732aed2a72636b760107b76dd49ea63fe7015ff5378c304d6384b519be0799d467b1f813528d88bf5f2e56619aeee6f7530b
|
7
|
+
data.tar.gz: 42e0731d46a569210842806b83b569921facd185109ed123aa5488e83ac5d985dfe15b2f58a6191226e057f7e3e3b39ae264f7f62725f1723b11cf9cf72fe8f9
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Peter Hollows
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# jruby_bridge
|
2
|
+
|
3
|
+
`jruby_bridge` proxies chunks of ruby code through to JRuby DRB Server and fetches the results.
|
4
|
+
|
5
|
+
This is useful for situations like having to plug your freshly minted Ruby app into some godawful legacy enterprise database, or other scenarios laced with java (we nearly called this barge_pole).
|
6
|
+
|
7
|
+
Based on, and forked from https://github.com/mkfs/jruby-bridge
|
8
|
+
"See http://entrenchant.blogspot.com/2012/07/drb-jruby-bridge.html for full discussion."
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
gem 'jruby_bridge'
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
$ gem install jruby_bridge
|
23
|
+
|
24
|
+
Then pat a kitten :tiger:
|
25
|
+
|
26
|
+
## Usage by Example
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
require 'jruby_bridge'
|
30
|
+
|
31
|
+
# Start the JRuby service process
|
32
|
+
JRubyBridge::Service.with_service do
|
33
|
+
|
34
|
+
# Now, every new SomeClass lives remotely
|
35
|
+
SomeClass.send :include, JRubyBridge::ObjectProxy
|
36
|
+
|
37
|
+
# Make a remote object
|
38
|
+
remote_object = SomeClass.new 'some', 'args'
|
39
|
+
|
40
|
+
# executes in the JRuby process
|
41
|
+
new_object = remote_object.do_stuff
|
42
|
+
|
43
|
+
# also in the JRuby process (pass by ref)
|
44
|
+
new_object.do_more_stuff
|
45
|
+
|
46
|
+
# lambdas are executed in this process
|
47
|
+
new_object.each { |thing| process thing }
|
48
|
+
|
49
|
+
end # Stop the JRuby service process
|
50
|
+
```
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
# You can also control the service manually
|
54
|
+
JRubyBridge::Service.start
|
55
|
+
JRubyBridge::Service.stop
|
56
|
+
```
|
57
|
+
|
58
|
+
## TODO
|
59
|
+
|
60
|
+
1. Ahh, some tests?
|
61
|
+
2. Convince the Enterprise to stop using commercial databases
|
62
|
+
3. Lazy-launching of the service process
|
63
|
+
4. Timeouts on the service process?
|
64
|
+
|
65
|
+
## Contributing
|
66
|
+
|
67
|
+
1. Fork it
|
68
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
69
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
70
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
71
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'jruby_bridge/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "jruby_bridge"
|
8
|
+
spec.version = JrubyBridge::VERSION
|
9
|
+
spec.authors = ["mkfs", "Peter Hollows"]
|
10
|
+
spec.email = ["peter.hollows@gmail.com"]
|
11
|
+
spec.description = %q{jruby_bridge proxies chunks of ruby code through to JRuby DRB Server and fetches the results.}
|
12
|
+
spec.summary = spec.description
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
end
|
data/lib/jruby_bridge.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'jruby_bridge/service'
|
2
|
+
|
3
|
+
module JRubyBridge
|
4
|
+
|
5
|
+
=begin rdoc
|
6
|
+
A module that patches initialization behavior to cause
|
7
|
+
new instances to reside on the JRuby DRb service.
|
8
|
+
=end
|
9
|
+
module ObjectProxy
|
10
|
+
|
11
|
+
def self.included(base)
|
12
|
+
base.class_eval do
|
13
|
+
include DRb::DRbUndumped
|
14
|
+
|
15
|
+
def self.new(*args)
|
16
|
+
service = Service.new_drb_object
|
17
|
+
service.proxy_new(self, *args)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'drb'
|
4
|
+
|
5
|
+
=begin rdoc
|
6
|
+
A Ruby class for launching a JRuby application in a child process, using
|
7
|
+
DRuby to communicate between them.
|
8
|
+
=end
|
9
|
+
module JRubyBridge
|
10
|
+
|
11
|
+
class JRubyExecError < StandardError; end
|
12
|
+
class DRbConnectionError < StandardError; end
|
13
|
+
|
14
|
+
=begin rdoc
|
15
|
+
A Ruby-managed JRuby application.
|
16
|
+
=end
|
17
|
+
class Service
|
18
|
+
# Path to JRuby application
|
19
|
+
DAEMON = File.join(File.dirname(__FILE__), 'server.rb')
|
20
|
+
# Port to listen on in JRuby
|
21
|
+
PORT = 44344
|
22
|
+
# Time to allow JRuby to initialize, in 100-ms increments
|
23
|
+
TIMEOUT = 300
|
24
|
+
|
25
|
+
def proxy_new(klass, *args)
|
26
|
+
klass.new *args
|
27
|
+
end
|
28
|
+
|
29
|
+
def stop
|
30
|
+
DRb.stop_service
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.with_service(&block)
|
34
|
+
start
|
35
|
+
yield
|
36
|
+
ensure
|
37
|
+
stop
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.start
|
41
|
+
return @pid if @pid
|
42
|
+
cls = self
|
43
|
+
@pid = Process.fork do
|
44
|
+
exit(cls.exec PORT)
|
45
|
+
end
|
46
|
+
# TODO : check child exit status and raise JRubyExecError
|
47
|
+
Process.detach(@pid)
|
48
|
+
|
49
|
+
connected = false
|
50
|
+
TIMEOUT.times do
|
51
|
+
begin
|
52
|
+
DRb::DRbObject.new_with_uri(default_uri).to_s
|
53
|
+
connected = true
|
54
|
+
break
|
55
|
+
rescue DRb::DRbConnError
|
56
|
+
sleep 0.1
|
57
|
+
end
|
58
|
+
end
|
59
|
+
raise DRbConnectionError.new("Could not connect to #{default_uri}") if \
|
60
|
+
(! connected)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.stop
|
64
|
+
service_send :stop
|
65
|
+
end
|
66
|
+
|
67
|
+
# Replace current process with JRuby running JRubyBridge::Service
|
68
|
+
def self.exec(port)
|
69
|
+
jruby = get_jruby
|
70
|
+
command = "#{jruby} #{DAEMON} #{port || ''}"
|
71
|
+
puts "Running #{command}"
|
72
|
+
Kernel.exec command if jruby
|
73
|
+
|
74
|
+
# Note: a raised exception goes nowhere: instead use exit status
|
75
|
+
$stderr.puts "No JRUBY found!"
|
76
|
+
return 1
|
77
|
+
end
|
78
|
+
|
79
|
+
# Called by the server script in JRuby context
|
80
|
+
def self.drb_start(port)
|
81
|
+
port ||= PORT
|
82
|
+
|
83
|
+
DRb.start_service "druby://localhost:#{port.to_i}", self.new
|
84
|
+
|
85
|
+
cls = self
|
86
|
+
trap('HUP') { DRb.stop_service; cls.drb_start(port) }
|
87
|
+
trap('INT') { puts 'Stopping jruby service'; DRb.stop_service }
|
88
|
+
|
89
|
+
DRb.thread.join
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.default_uri
|
93
|
+
"druby://localhost:#{PORT}"
|
94
|
+
end
|
95
|
+
|
96
|
+
# Return command to launch JRuby interpreter
|
97
|
+
def self.get_jruby
|
98
|
+
# FIXME: this should detect RVM first and system second
|
99
|
+
|
100
|
+
# 1. detect system JRuby
|
101
|
+
jruby = `which jruby`
|
102
|
+
return jruby.chomp if (! jruby.empty?)
|
103
|
+
|
104
|
+
# 2. detect RVM-managed JRuby
|
105
|
+
return nil if (`which rvm`).empty?
|
106
|
+
jruby = `rvm list`.split("\n").select { |rb| rb.include? 'jruby' }.first
|
107
|
+
return nil if (! jruby)
|
108
|
+
|
109
|
+
"rvm #{jruby.strip.split(' ').first} do ruby "
|
110
|
+
end
|
111
|
+
|
112
|
+
# this will return a new DRuby connection
|
113
|
+
def self.service_send(method, *args)
|
114
|
+
begin
|
115
|
+
new_drb_object.tap { |obj| obj.send(method, *args) }
|
116
|
+
rescue DRb::DRbConnError => e
|
117
|
+
# $stderr.puts e.backtrace.join("\n")
|
118
|
+
raise DRbConnectionError.new(e.message)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.new_drb_object
|
123
|
+
DRb::DRbObject.new_with_uri(default_uri)
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
end
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jruby_bridge
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- mkfs
|
8
|
+
- Peter Hollows
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-06-14 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ~>
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.3'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.3'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
description: jruby_bridge proxies chunks of ruby code through to JRuby DRB Server
|
43
|
+
and fetches the results.
|
44
|
+
email:
|
45
|
+
- peter.hollows@gmail.com
|
46
|
+
executables: []
|
47
|
+
extensions: []
|
48
|
+
extra_rdoc_files: []
|
49
|
+
files:
|
50
|
+
- .gitignore
|
51
|
+
- Gemfile
|
52
|
+
- LICENSE.txt
|
53
|
+
- README.md
|
54
|
+
- Rakefile
|
55
|
+
- jruby_bridge.gemspec
|
56
|
+
- lib/jruby_bridge.rb
|
57
|
+
- lib/jruby_bridge/object_proxy.rb
|
58
|
+
- lib/jruby_bridge/server.rb
|
59
|
+
- lib/jruby_bridge/service.rb
|
60
|
+
- lib/jruby_bridge/version.rb
|
61
|
+
homepage: ''
|
62
|
+
licenses:
|
63
|
+
- MIT
|
64
|
+
metadata: {}
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
requirements: []
|
80
|
+
rubyforge_project:
|
81
|
+
rubygems_version: 2.0.3
|
82
|
+
signing_key:
|
83
|
+
specification_version: 4
|
84
|
+
summary: jruby_bridge proxies chunks of ruby code through to JRuby DRB Server and
|
85
|
+
fetches the results.
|
86
|
+
test_files: []
|