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.
@@ -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: []