theine 0.0.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.
- data/bin/theine +2 -0
- data/bin/theine_server +2 -0
- data/lib/theine.rb +0 -0
- data/lib/theine/client.rb +90 -0
- data/lib/theine/instance.rb +114 -0
- data/lib/theine/server.rb +75 -0
- metadata +53 -0
data/bin/theine
ADDED
data/bin/theine_server
ADDED
data/lib/theine.rb
ADDED
File without changes
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'drb/drb'
|
2
|
+
require 'readline'
|
3
|
+
|
4
|
+
PRAILS_BASE_PORT = 11000
|
5
|
+
|
6
|
+
class IOUndumpedProxy
|
7
|
+
include DRb::DRbUndumped
|
8
|
+
|
9
|
+
def initialize(obj)
|
10
|
+
@obj = obj
|
11
|
+
end
|
12
|
+
|
13
|
+
def completion_proc=(val)
|
14
|
+
if @obj.respond_to? :completion_proc=
|
15
|
+
@obj.completion_proc = val
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def completion_proc
|
20
|
+
@obj.completion_proc if @obj.respond_to? :completion_proc
|
21
|
+
end
|
22
|
+
|
23
|
+
def readline(prompt)
|
24
|
+
if ::Readline == @obj
|
25
|
+
@obj.readline(prompt, true)
|
26
|
+
elsif @obj.method(:readline).arity == 1
|
27
|
+
@obj.readline(prompt)
|
28
|
+
else
|
29
|
+
$stdout.print prompt
|
30
|
+
@obj.readline
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def puts(*lines)
|
35
|
+
@obj.puts(*lines)
|
36
|
+
end
|
37
|
+
|
38
|
+
def print(*objs)
|
39
|
+
@obj.print(*objs)
|
40
|
+
end
|
41
|
+
|
42
|
+
def write(data)
|
43
|
+
@obj.write data
|
44
|
+
end
|
45
|
+
|
46
|
+
def <<(data)
|
47
|
+
@obj << data
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
51
|
+
def flush
|
52
|
+
@obj.flush
|
53
|
+
end
|
54
|
+
|
55
|
+
# Some versions of Pry expect $stdout or its output objects to respond to
|
56
|
+
# this message.
|
57
|
+
def tty?
|
58
|
+
false
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
argv = ARGV.dup
|
63
|
+
ARGV.clear
|
64
|
+
|
65
|
+
DRb.start_service
|
66
|
+
|
67
|
+
i = 1
|
68
|
+
begin
|
69
|
+
balancer = DRbObject.new_with_uri("druby://localhost:#{PRAILS_BASE_PORT}")
|
70
|
+
sleep 0.1 until port = balancer.get_port
|
71
|
+
prails = DRbObject.new_with_uri("druby://localhost:#{port}")
|
72
|
+
rescue DRb::DRbConnError
|
73
|
+
sleep 0.5
|
74
|
+
putc "."
|
75
|
+
i += 1
|
76
|
+
retry
|
77
|
+
end
|
78
|
+
putc "\n"
|
79
|
+
|
80
|
+
trap('INT') {
|
81
|
+
%x[kill -2 #{prails.pid}]
|
82
|
+
}
|
83
|
+
|
84
|
+
prails.stdin = IOUndumpedProxy.new($stdin)
|
85
|
+
prails.stdout = IOUndumpedProxy.new($stdout)
|
86
|
+
prails.stderr = IOUndumpedProxy.new($stderr)
|
87
|
+
begin
|
88
|
+
prails.command_rails(argv)
|
89
|
+
rescue DRb::DRbConnError
|
90
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
root_path = ARGV[2]
|
2
|
+
APP_PATH = "#{root_path}/config/application"
|
3
|
+
require "#{root_path}/config/boot"
|
4
|
+
require "#{root_path}/config/environment"
|
5
|
+
require 'drb/drb'
|
6
|
+
|
7
|
+
$real_stdout = $stdout
|
8
|
+
$real_stderr = $stderr
|
9
|
+
|
10
|
+
class PrailsServer
|
11
|
+
attr_reader :stdin, :stdout, :stderr
|
12
|
+
InputProxy = Struct.new :input do
|
13
|
+
# Reads a line from the input
|
14
|
+
def readline(prompt)
|
15
|
+
case readline_arity
|
16
|
+
when 1 then input.readline(prompt)
|
17
|
+
else input.readline
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def completion_proc=(val)
|
22
|
+
input.completion_proc = val
|
23
|
+
end
|
24
|
+
|
25
|
+
def readline_arity
|
26
|
+
input.method_missing(:method, :readline).arity
|
27
|
+
rescue NameError
|
28
|
+
0
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize
|
33
|
+
@pumps = []
|
34
|
+
end
|
35
|
+
|
36
|
+
def command_rails(argv)
|
37
|
+
rails_reload!
|
38
|
+
|
39
|
+
ARGV.clear
|
40
|
+
ARGV.concat(argv)
|
41
|
+
|
42
|
+
require 'pry'
|
43
|
+
::Rails.application.config.console = Pry
|
44
|
+
|
45
|
+
Pry.config.input = stdin
|
46
|
+
Pry.config.output = stdout
|
47
|
+
|
48
|
+
require 'rails/commands'
|
49
|
+
sleep 0.1 # allow Pumps to finish
|
50
|
+
DRb.stop_service
|
51
|
+
end
|
52
|
+
|
53
|
+
def stdin=(value)
|
54
|
+
@stdin = InputProxy.new(value)
|
55
|
+
$stdin = @stdin
|
56
|
+
end
|
57
|
+
|
58
|
+
def stdout=(value)
|
59
|
+
$orig_stdout = $stdout
|
60
|
+
@stdout = value
|
61
|
+
r, w = IO.pipe
|
62
|
+
$stdout = w
|
63
|
+
@pumps << Pump.new(r, @stdout)
|
64
|
+
end
|
65
|
+
|
66
|
+
def stderr=(value)
|
67
|
+
$orig_stderr = $stderr
|
68
|
+
@stderr = value
|
69
|
+
r, w = IO.pipe
|
70
|
+
$stderr = w
|
71
|
+
@pumps << Pump.new(r, @stderr)
|
72
|
+
end
|
73
|
+
|
74
|
+
def pid
|
75
|
+
::Process.pid
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
def rails_reload!
|
80
|
+
ActionDispatch::Reloader.cleanup!
|
81
|
+
ActionDispatch::Reloader.prepare!
|
82
|
+
end
|
83
|
+
|
84
|
+
class Pump < Thread
|
85
|
+
def initialize(input, output)
|
86
|
+
if output
|
87
|
+
@input = input
|
88
|
+
@output = output
|
89
|
+
super(&method(:main))
|
90
|
+
else
|
91
|
+
close_stream(input)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
def main
|
97
|
+
while buf = @input.sysread(1024)
|
98
|
+
@output.print(buf)
|
99
|
+
@output.flush
|
100
|
+
end
|
101
|
+
ensure
|
102
|
+
@output.close
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
base_port = ARGV[0]
|
108
|
+
instance_port = ARGV[1]
|
109
|
+
DRb.start_service("druby://localhost:#{instance_port}", PrailsServer.new)
|
110
|
+
|
111
|
+
balancer = DRbObject.new_with_uri("druby://localhost:#{base_port}")
|
112
|
+
balancer.instance_boot(instance_port)
|
113
|
+
|
114
|
+
DRb.thread.join
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'drb/drb'
|
2
|
+
require 'thread'
|
3
|
+
|
4
|
+
PRAILS_BASE_PORT = 11000
|
5
|
+
PRAILS_MAX_PORT = 11100
|
6
|
+
MIN_FREE_INSTANCES = 2
|
7
|
+
RAILS_APP_ROOT = Dir.pwd
|
8
|
+
|
9
|
+
class PrailsServer
|
10
|
+
include DRb::DRbUndumped
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@instances = []
|
14
|
+
@spawning = []
|
15
|
+
|
16
|
+
@available_ports = ((PRAILS_BASE_PORT + 1)..PRAILS_MAX_PORT).to_a
|
17
|
+
@check_mutex = Mutex.new
|
18
|
+
@instances_mutex = Mutex.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_instance
|
22
|
+
path = File.expand_path('../instance.rb', __FILE__)
|
23
|
+
port = @available_ports.shift
|
24
|
+
puts "(spawn #{port})"
|
25
|
+
spawn("ruby", path, PRAILS_BASE_PORT.to_s, port.to_s, RAILS_APP_ROOT)
|
26
|
+
@instances_mutex.synchronize { @spawning << 1 }
|
27
|
+
end
|
28
|
+
|
29
|
+
def instance_boot(port)
|
30
|
+
puts "+ instance #{port}"
|
31
|
+
|
32
|
+
@instances_mutex.synchronize do
|
33
|
+
@spawning.pop
|
34
|
+
@instances << port
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_port
|
39
|
+
add_instance if all_size == 0
|
40
|
+
|
41
|
+
port = nil
|
42
|
+
while port.nil? && all_size > 0
|
43
|
+
@instances_mutex.synchronize do
|
44
|
+
port = @instances.shift
|
45
|
+
end
|
46
|
+
sleep 0.1 unless port
|
47
|
+
end
|
48
|
+
|
49
|
+
Thread.new { check_min_free_instances }
|
50
|
+
|
51
|
+
port
|
52
|
+
end
|
53
|
+
|
54
|
+
def check_min_free_instances
|
55
|
+
if @check_mutex.try_lock
|
56
|
+
# TODO: mutex, and dont do it if already in progress
|
57
|
+
# do this in thread
|
58
|
+
while all_size < MIN_FREE_INSTANCES
|
59
|
+
sleep 0.1 until @instances_mutex.synchronize { @spawning.empty? }
|
60
|
+
add_instance
|
61
|
+
end
|
62
|
+
@check_mutex.unlock
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def all_size
|
67
|
+
@instances_mutex.synchronize { @instances.size + @spawning.size }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
server = PrailsServer.new
|
72
|
+
DRb.start_service("druby://localhost:#{PRAILS_BASE_PORT}", server)
|
73
|
+
|
74
|
+
server.check_min_free_instances
|
75
|
+
DRb.thread.join
|
metadata
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: theine
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jan Berdajs
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-10-01 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: A Rails preloader for JRuby
|
15
|
+
email: mrbrdo@mrbrdo.net
|
16
|
+
executables:
|
17
|
+
- theine
|
18
|
+
- theine_server
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- lib/theine.rb
|
23
|
+
- lib/theine/client.rb
|
24
|
+
- lib/theine/server.rb
|
25
|
+
- lib/theine/instance.rb
|
26
|
+
- bin/theine
|
27
|
+
- bin/theine_server
|
28
|
+
homepage: https://github.com/mrbrdo/theine
|
29
|
+
licenses:
|
30
|
+
- MIT
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
require_paths:
|
34
|
+
- lib
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
none: false
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
none: false
|
47
|
+
requirements: []
|
48
|
+
rubyforge_project:
|
49
|
+
rubygems_version: 1.8.24
|
50
|
+
signing_key:
|
51
|
+
specification_version: 3
|
52
|
+
summary: Theine
|
53
|
+
test_files: []
|