theine 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env ruby
2
+ require 'theine/client'
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env ruby
2
+ require 'theine/server'
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: []