rsense-server 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/Gemfile +14 -0
- data/Guardfile +5 -0
- data/LICENSE.txt +1 -0
- data/README.md +51 -0
- data/Rakefile +9 -0
- data/bin/_rsense.rb +115 -0
- data/config/puma.rb +2 -0
- data/lib/rsense/server/code.rb +38 -0
- data/lib/rsense/server/command/completion_result.rb +11 -0
- data/lib/rsense/server/command/special_meth.rb +18 -0
- data/lib/rsense/server/command/type_inference_method.rb +24 -0
- data/lib/rsense/server/command.rb +239 -0
- data/lib/rsense/server/config.rb +70 -0
- data/lib/rsense/server/gem_path.rb +18 -0
- data/lib/rsense/server/listeners/find_definition_event_listener.rb +91 -0
- data/lib/rsense/server/listeners/where_event_listener.rb +39 -0
- data/lib/rsense/server/load_path.rb +62 -0
- data/lib/rsense/server/options.rb +85 -0
- data/lib/rsense/server/parser.rb +17 -0
- data/lib/rsense/server/path_info.rb +17 -0
- data/lib/rsense/server/project.rb +24 -0
- data/lib/rsense/server/version.rb +5 -0
- data/lib/rsense/server.rb +18 -0
- data/rsense-server.gemspec +35 -0
- data/spec/fixtures/config_fixture/.rsense +4 -0
- data/spec/fixtures/deeply/nested/thing.rb +0 -0
- data/spec/fixtures/find_def_sample.json +10 -0
- data/spec/fixtures/sample.json +10 -0
- data/spec/fixtures/test_gem/.gitignore +22 -0
- data/spec/fixtures/test_gem/Gemfile +4 -0
- data/spec/fixtures/test_gem/LICENSE.txt +22 -0
- data/spec/fixtures/test_gem/README.md +29 -0
- data/spec/fixtures/test_gem/Rakefile +2 -0
- data/spec/fixtures/test_gem/lib/sample/version.rb +3 -0
- data/spec/fixtures/test_gem/lib/sample.rb +16 -0
- data/spec/fixtures/test_gem/sample.gemspec +23 -0
- data/spec/fixtures/test_gem/test.json +10 -0
- data/spec/rsense/server/code_spec.rb +44 -0
- data/spec/rsense/server/command/special_meth_spec.rb +23 -0
- data/spec/rsense/server/command_spec.rb +108 -0
- data/spec/rsense/server/config_spec.rb +27 -0
- data/spec/rsense/server/gem_path_spec.rb +16 -0
- data/spec/rsense/server/load_path_spec.rb +63 -0
- data/spec/rsense/server/options_spec.rb +33 -0
- data/spec/rsense/server/path_info_spec.rb +11 -0
- data/spec/rsense/server/project_spec.rb +18 -0
- data/spec/rsense/server_spec.rb +7 -0
- data/spec/spec_helper.rb +16 -0
- data/vendor/gems/puma-2.8.2-java/COPYING +55 -0
- data/vendor/gems/puma-2.8.2-java/DEPLOYMENT.md +92 -0
- data/vendor/gems/puma-2.8.2-java/Gemfile +17 -0
- data/vendor/gems/puma-2.8.2-java/History.txt +532 -0
- data/vendor/gems/puma-2.8.2-java/LICENSE +26 -0
- data/vendor/gems/puma-2.8.2-java/Manifest.txt +68 -0
- data/vendor/gems/puma-2.8.2-java/README.md +251 -0
- data/vendor/gems/puma-2.8.2-java/Rakefile +158 -0
- data/vendor/gems/puma-2.8.2-java/bin/puma +10 -0
- data/vendor/gems/puma-2.8.2-java/bin/puma-wild +17 -0
- data/vendor/gems/puma-2.8.2-java/bin/pumactl +12 -0
- data/vendor/gems/puma-2.8.2-java/docs/config.md +0 -0
- data/vendor/gems/puma-2.8.2-java/docs/nginx.md +80 -0
- data/vendor/gems/puma-2.8.2-java/docs/signals.md +42 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/PumaHttp11Service.java +17 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/ext_help.h +15 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/extconf.rb +8 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/http11_parser.c +1225 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/http11_parser.h +64 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/http11_parser.java.rl +161 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/http11_parser.rl +146 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/http11_parser_common.rl +54 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/io_buffer.c +155 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/mini_ssl.c +195 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/org/jruby/puma/Http11.java +225 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/org/jruby/puma/Http11Parser.java +488 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/org/jruby/puma/MiniSSL.java +289 -0
- data/vendor/gems/puma-2.8.2-java/ext/puma_http11/puma_http11.c +491 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/accept_nonblock.rb +23 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/app/status.rb +59 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/binder.rb +298 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/capistrano.rb +86 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/cli.rb +587 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/client.rb +289 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/cluster.rb +389 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/compat.rb +18 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/configuration.rb +377 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/const.rb +165 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/control_cli.rb +251 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/daemon_ext.rb +25 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/delegation.rb +11 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/detect.rb +4 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/events.rb +130 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/io_buffer.rb +7 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/java_io_buffer.rb +45 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/jruby_restart.rb +83 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/minissl.rb +148 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/null_io.rb +34 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/puma_http11.jar +0 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/rack_default.rb +7 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/rack_patch.rb +45 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/reactor.rb +183 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/runner.rb +146 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/server.rb +801 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/single.rb +102 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/tcp_logger.rb +32 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/thread_pool.rb +185 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma/util.rb +9 -0
- data/vendor/gems/puma-2.8.2-java/lib/puma.rb +14 -0
- data/vendor/gems/puma-2.8.2-java/lib/rack/handler/puma.rb +66 -0
- data/vendor/gems/puma-2.8.2-java/puma.gemspec +55 -0
- data/vendor/gems/puma-2.8.2-java/test/test_app_status.rb +92 -0
- data/vendor/gems/puma-2.8.2-java/test/test_cli.rb +173 -0
- data/vendor/gems/puma-2.8.2-java/test/test_config.rb +26 -0
- data/vendor/gems/puma-2.8.2-java/test/test_http10.rb +27 -0
- data/vendor/gems/puma-2.8.2-java/test/test_http11.rb +144 -0
- data/vendor/gems/puma-2.8.2-java/test/test_integration.rb +165 -0
- data/vendor/gems/puma-2.8.2-java/test/test_iobuffer.rb +38 -0
- data/vendor/gems/puma-2.8.2-java/test/test_minissl.rb +25 -0
- data/vendor/gems/puma-2.8.2-java/test/test_null_io.rb +31 -0
- data/vendor/gems/puma-2.8.2-java/test/test_persistent.rb +238 -0
- data/vendor/gems/puma-2.8.2-java/test/test_puma_server.rb +323 -0
- data/vendor/gems/puma-2.8.2-java/test/test_rack_handler.rb +10 -0
- data/vendor/gems/puma-2.8.2-java/test/test_rack_server.rb +141 -0
- data/vendor/gems/puma-2.8.2-java/test/test_tcp_rack.rb +42 -0
- data/vendor/gems/puma-2.8.2-java/test/test_thread_pool.rb +156 -0
- data/vendor/gems/puma-2.8.2-java/test/test_unix_socket.rb +39 -0
- data/vendor/gems/puma-2.8.2-java/test/test_ws.rb +89 -0
- data/vendor/gems/puma-2.8.2-java/tools/jungle/README.md +9 -0
- data/vendor/gems/puma-2.8.2-java/tools/jungle/init.d/README.md +54 -0
- data/vendor/gems/puma-2.8.2-java/tools/jungle/init.d/puma +332 -0
- data/vendor/gems/puma-2.8.2-java/tools/jungle/init.d/run-puma +3 -0
- data/vendor/gems/puma-2.8.2-java/tools/jungle/upstart/README.md +61 -0
- data/vendor/gems/puma-2.8.2-java/tools/jungle/upstart/puma-manager.conf +31 -0
- data/vendor/gems/puma-2.8.2-java/tools/jungle/upstart/puma.conf +63 -0
- data/vendor/gems/puma-2.8.2-java/tools/trickletest.rb +45 -0
- metadata +389 -0
@@ -0,0 +1,108 @@
|
|
1
|
+
require "pathname"
|
2
|
+
require "json"
|
3
|
+
require_relative "../../spec_helper.rb"
|
4
|
+
|
5
|
+
describe Rsense::Server::Command::Command do
|
6
|
+
before do
|
7
|
+
@json_path = Pathname.new("spec/fixtures/sample.json")
|
8
|
+
@json = JSON.parse(@json_path.read)
|
9
|
+
@options = Rsense::Server::Options.new(@json)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "can be initialized" do
|
13
|
+
Rsense::Server::Command::Command.new(@options)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "finding dependencies" do
|
17
|
+
Dependency = Struct.new(:name, :full_name, :path)
|
18
|
+
Project = Struct.new(:load_path, :gem_path, :stubs)
|
19
|
+
|
20
|
+
before do
|
21
|
+
@dependencies = [
|
22
|
+
Dependency.new("foo", "foo.1.2", ["/foo/bar/baz"]),
|
23
|
+
Dependency.new("scooby", "scooby.1.2", ["/scooby/dooby/doo"])
|
24
|
+
]
|
25
|
+
@loadpath = [
|
26
|
+
"spec/fixtures",
|
27
|
+
"/bada/bing/bang/boom"
|
28
|
+
]
|
29
|
+
@gempath = [
|
30
|
+
"/fee/fi/fo/fum",
|
31
|
+
"/i/smell/the/blood/of/an/englishman"
|
32
|
+
]
|
33
|
+
@stubs = Dir.glob(Rsense::BUILTIN.join("**/*.rb"))
|
34
|
+
@project = Project.new(@loadpath, @gempath, @stubs)
|
35
|
+
@command = Rsense::Server::Command::Command.new(@options)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "finds the dependency" do
|
39
|
+
matches = @command.dependency_matches(@dependencies, "foo")
|
40
|
+
matches.first.to_s.must_match(/baz/)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "does not find a dependency which is not there" do
|
44
|
+
@command.dependency_matches(@dependencies, "scoby").must_be_empty
|
45
|
+
end
|
46
|
+
|
47
|
+
it "finds the path in the load_path" do
|
48
|
+
@command.load_path_matches(@project, "def_sample").size.must_equal(1)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "gathers the lib directory paths from the dependencies" do
|
52
|
+
deps = [
|
53
|
+
Dependency.new("foo", "foo.1.2", ["/foo/lib/foo.rb"]),
|
54
|
+
Dependency.new("scooby", "scooby.1.2", ["/scooby/lib/scooby.rb"])
|
55
|
+
]
|
56
|
+
paths = @command.dependency_paths(deps)
|
57
|
+
paths.size.must_equal(2)
|
58
|
+
paths.first.to_s.must_match(/\/foo\/lib$/)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "finds a deeply nested path" do
|
62
|
+
dep_paths = [Pathname.new("spec/fixtures/deeply"), Pathname.new("foo/bar/baz")]
|
63
|
+
matches = @command.deep_check(@gempath, dep_paths, "thing")
|
64
|
+
matches.first.must_match(/nested/)
|
65
|
+
matches.size.must_equal(1)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "finds the stubs" do
|
69
|
+
matches = @command.stub_matches(@project, "_builtin")
|
70
|
+
matches.size.must_equal(1)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "finds the _builtin" do
|
74
|
+
@command.builtin_path(@project).to_s.must_match(/_builtin/)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "completions" do
|
79
|
+
require 'json'
|
80
|
+
|
81
|
+
class Testscript
|
82
|
+
attr_accessor :json_path, :json, :options, :command, :name, :file, :project
|
83
|
+
|
84
|
+
def initialize
|
85
|
+
@json_path = Pathname.new("spec/fixtures/test_gem/test.json").expand_path
|
86
|
+
@json = JSON.parse(@json_path.read)
|
87
|
+
@options = Rsense::Server::Options.new(@json)
|
88
|
+
@command = Rsense::Server::Command::Command.new(@options)
|
89
|
+
@name = "sample"
|
90
|
+
@file = @options.project_path
|
91
|
+
@project = Rsense::Server::Project.new(@name, @file)
|
92
|
+
end
|
93
|
+
|
94
|
+
def code_complete
|
95
|
+
@command.code_completion(@options.file, @options.location)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
before do
|
100
|
+
@test = Testscript.new
|
101
|
+
end
|
102
|
+
|
103
|
+
it "returns completions" do
|
104
|
+
@test.code_complete.size.must_equal(51)
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "filetree"
|
2
|
+
require_relative "../../spec_helper"
|
3
|
+
|
4
|
+
describe Rsense::Server::Config do
|
5
|
+
before do
|
6
|
+
@path = "spec/fixtures/config_fixture"
|
7
|
+
@conf_path = FileTree.new("spec/fixtures/config_fixture/.rsense").expand_path
|
8
|
+
@config = Rsense::Server::Config.new
|
9
|
+
end
|
10
|
+
|
11
|
+
it "searches for a config file" do
|
12
|
+
search = @config.search(@path)
|
13
|
+
search.to_s.must_match(/spec\/fixtures\/config_fixture\/\.rsense/)
|
14
|
+
@config.searched.size.must_equal(1)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "sets the port" do
|
18
|
+
options = @config.options(@conf_path)
|
19
|
+
@config.port.must_equal(123456)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "sets ignores" do
|
23
|
+
options = @config.options(@conf_path)
|
24
|
+
@config.ignores.must_include(".foo")
|
25
|
+
@config.ignores.must_include(".bar")
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative "../../spec_helper.rb"
|
2
|
+
|
3
|
+
describe Rsense::Server::GemPath do
|
4
|
+
|
5
|
+
it "returns the list of Gem paths" do
|
6
|
+
Rsense::Server::GemPath.stub :fetch, ["/path/to/the/gems"] do
|
7
|
+
Rsense::Server::GemPath.paths.first.must_match(/\/path\/to\/the\/gems/)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it "excludes paths inside jruby\'s jars" do
|
12
|
+
Rsense::Server::GemPath.stub :fetch, ["file: file in a jar"] do
|
13
|
+
Rsense::Server::GemPath.paths.wont_include("file: file in a jar")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require "pathname"
|
2
|
+
require_relative "../../spec_helper.rb"
|
3
|
+
|
4
|
+
describe Rsense::Server::LoadPath do
|
5
|
+
it "lists loads paths" do
|
6
|
+
Rsense::Server::LoadPath.stub :fetch,["/some/path/to/load"] do
|
7
|
+
Rsense::Server::LoadPath.paths.first.must_match(/\/some\/path\/to\/load/)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it "does not list paths inside a jar" do
|
12
|
+
Rsense::Server::LoadPath.stub :fetch, ["file:path/in/jar"] do
|
13
|
+
Rsense::Server::LoadPath.paths.wont_include("file:path/in/jar")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "with project" do
|
18
|
+
ProjectMock = Struct.new(:path)
|
19
|
+
|
20
|
+
before do
|
21
|
+
@proj_path = "spec/fixtures/load_path_fixture"
|
22
|
+
@project = ProjectMock.new(@proj_path)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "checks for a Gemfile.lock" do
|
26
|
+
Rsense::Server::LoadPath.find_gemfile(@project.path).to_s.must_match(/Gemfile/)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "checks paths for correct version" do
|
30
|
+
fake_paths = ["1", "2", "3"]
|
31
|
+
checked = Rsense::Server::LoadPath.check_version(fake_paths, "2")
|
32
|
+
checked.size.must_equal(1)
|
33
|
+
checked.must_include("2")
|
34
|
+
checked.wont_include("1")
|
35
|
+
checked.wont_include("3")
|
36
|
+
end
|
37
|
+
|
38
|
+
it "returns a list of Gems" do
|
39
|
+
class SpecMock
|
40
|
+
def name
|
41
|
+
"mock"
|
42
|
+
end
|
43
|
+
|
44
|
+
def version
|
45
|
+
"2"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
lfile = Object.new
|
50
|
+
|
51
|
+
def lfile.specs
|
52
|
+
[SpecMock.new]
|
53
|
+
end
|
54
|
+
|
55
|
+
Gem.stub :find_files, ["/stubbed/path-2"] do
|
56
|
+
ret_gems = Rsense::Server::LoadPath.gem_info(lfile).first
|
57
|
+
ret_gems.name.must_match(/mock/)
|
58
|
+
ret_gems.full_name.must_match(/mock-2/)
|
59
|
+
ret_gems.path.first.must_match(/stubbed/)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "pathname"
|
2
|
+
require "json"
|
3
|
+
require_relative "../../spec_helper"
|
4
|
+
|
5
|
+
describe Rsense::Server::Options do
|
6
|
+
before do
|
7
|
+
@json_path = Pathname.new("spec/fixtures/sample.json")
|
8
|
+
@json = JSON.parse(@json_path.read)
|
9
|
+
@options = Rsense::Server::Options.new(@json)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "has a command" do
|
13
|
+
@options.command.must_match(/code_completion/)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "has a project path" do
|
17
|
+
@options.project_path.to_s.must_match(/code/)
|
18
|
+
@options.project_path.class.must_equal(Pathname)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "has code" do
|
22
|
+
@options.code.must_match(/def/)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "has a location" do
|
26
|
+
@options.location["row"].must_equal(2)
|
27
|
+
@options.location["column"].must_equal(10)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "has a file" do
|
31
|
+
@options.file.to_s.must_match(/rsense\.rb/)
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require_relative "../../spec_helper.rb"
|
2
|
+
|
3
|
+
describe Rsense::Server::PathInfo do
|
4
|
+
it "knows where its home is" do
|
5
|
+
Rsense::Server::PathInfo::RSENSE_SERVER_HOME.to_s.must_match(/rsense-server$/)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "knows where to find the bin file" do
|
9
|
+
Rsense::Server::PathInfo.bin_path.to_s.must_match(/rsense-server\/bin\/_rsense.rb$/)
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative "../../spec_helper"
|
2
|
+
|
3
|
+
describe Rsense::Server::Project do
|
4
|
+
before do
|
5
|
+
@project = Rsense::Server::Project.new(__FILE__, File.dirname(__FILE__))
|
6
|
+
end
|
7
|
+
|
8
|
+
it "has stubs" do
|
9
|
+
stubs = @project.stubs.select { |e| e.to_s =~ /_builtin/ }
|
10
|
+
stubs.size.must_equal(1)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "tracks loaded features" do
|
14
|
+
@project.loaded << "feature"
|
15
|
+
@project.loaded?("feature").must_equal(true)
|
16
|
+
@project.loaded?("different").must_equal(false)
|
17
|
+
end
|
18
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require "minitest/reporters"
|
3
|
+
Minitest::Reporters.use!
|
4
|
+
|
5
|
+
require "rsense-core"
|
6
|
+
|
7
|
+
require_relative "../lib/rsense/server/command.rb"
|
8
|
+
require_relative "../lib/rsense/server/gem_path.rb"
|
9
|
+
require_relative "../lib/rsense/server/load_path.rb"
|
10
|
+
require_relative "../lib/rsense/server/options.rb"
|
11
|
+
require_relative "../lib/rsense/server/code.rb"
|
12
|
+
require_relative "../lib/rsense/server.rb"
|
13
|
+
require_relative "../lib/rsense/server/path_info.rb"
|
14
|
+
require_relative "../lib/rsense/server/command/special_meth.rb"
|
15
|
+
require_relative "../lib/rsense/server/project.rb"
|
16
|
+
require_relative "../lib/rsense/server/config.rb"
|
@@ -0,0 +1,55 @@
|
|
1
|
+
Mongrel Web Server (Mongrel) is copyrighted free software by Zed A. Shaw
|
2
|
+
<zedshaw at zedshaw dot com> You can redistribute it and/or modify it under
|
3
|
+
either the terms of the GPL or the conditions below:
|
4
|
+
|
5
|
+
1. You may make and give away verbatim copies of the source form of the
|
6
|
+
software without restriction, provided that you duplicate all of the
|
7
|
+
original copyright notices and associated disclaimers.
|
8
|
+
|
9
|
+
2. You may modify your copy of the software in any way, provided that
|
10
|
+
you do at least ONE of the following:
|
11
|
+
|
12
|
+
a) place your modifications in the Public Domain or otherwise make them
|
13
|
+
Freely Available, such as by posting said modifications to Usenet or an
|
14
|
+
equivalent medium, or by allowing the author to include your
|
15
|
+
modifications in the software.
|
16
|
+
|
17
|
+
b) use the modified software only within your corporation or
|
18
|
+
organization.
|
19
|
+
|
20
|
+
c) rename any non-standard executables so the names do not conflict with
|
21
|
+
standard executables, which must also be provided.
|
22
|
+
|
23
|
+
d) make other distribution arrangements with the author.
|
24
|
+
|
25
|
+
3. You may distribute the software in object code or executable
|
26
|
+
form, provided that you do at least ONE of the following:
|
27
|
+
|
28
|
+
a) distribute the executables and library files of the software,
|
29
|
+
together with instructions (in the manual page or equivalent) on where
|
30
|
+
to get the original distribution.
|
31
|
+
|
32
|
+
b) accompany the distribution with the machine-readable source of the
|
33
|
+
software.
|
34
|
+
|
35
|
+
c) give non-standard executables non-standard names, with
|
36
|
+
instructions on where to get the original software distribution.
|
37
|
+
|
38
|
+
d) make other distribution arrangements with the author.
|
39
|
+
|
40
|
+
4. You may modify and include the part of the software into any other
|
41
|
+
software (possibly commercial). But some files in the distribution
|
42
|
+
are not written by the author, so that they are not under this terms.
|
43
|
+
|
44
|
+
5. The scripts and library files supplied as input to or produced as
|
45
|
+
output from the software do not automatically fall under the
|
46
|
+
copyright of the software, but belong to whomever generated them,
|
47
|
+
and may be sold commercially, and may be aggregated with this
|
48
|
+
software.
|
49
|
+
|
50
|
+
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
51
|
+
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
52
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
53
|
+
PURPOSE.
|
54
|
+
|
55
|
+
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# Deployment engineering for puma
|
2
|
+
|
3
|
+
Puma is software that is expected to be run in a deployed environment eventually.
|
4
|
+
You can centainly use it as your dev server only, but most people look to use
|
5
|
+
it in their production deployments as well.
|
6
|
+
|
7
|
+
To that end, this is meant to serve as a foundation of wisdom how to do that
|
8
|
+
in a way that increases happiness and decreases downtime.
|
9
|
+
|
10
|
+
## Specifying puma
|
11
|
+
|
12
|
+
Most people want to do this by putting `gem "puma"` into their Gemfile, so we'll
|
13
|
+
go ahead and assume that. Go add it now... we'll wait.
|
14
|
+
|
15
|
+
|
16
|
+
Welcome back!
|
17
|
+
|
18
|
+
## Single vs Cluster mode
|
19
|
+
|
20
|
+
Puma was originally concieved as a thread-only webserver, but grew the ability to
|
21
|
+
also use processes in version 2.
|
22
|
+
|
23
|
+
Here are some rules of thumb:
|
24
|
+
|
25
|
+
### MRI
|
26
|
+
|
27
|
+
* Use cluster mode and set the number of workers to 1.5x the number of cpu cores
|
28
|
+
in the machine, minimum 2.
|
29
|
+
* Set the number of threads to desired concurrent requests / number of workers.
|
30
|
+
Puma defaults to 8 and thats a decent number.
|
31
|
+
|
32
|
+
#### Migrating from Unicorn
|
33
|
+
|
34
|
+
* If you're migrating from unicorn though, here are some settings to start with:
|
35
|
+
* Set workers to half the number of unicorn workers you're using
|
36
|
+
* Set threads to 2
|
37
|
+
* Enjoy 50% memory savings
|
38
|
+
* As you grow more confident in the thread safety of your app, you can tune the
|
39
|
+
workers down and the threads up.
|
40
|
+
|
41
|
+
#### Worker utilization
|
42
|
+
|
43
|
+
**How do you know if you're got enough (or too many workers)?**
|
44
|
+
|
45
|
+
A good question. Due to MRI's GIL, only one thread can be executing at a time.
|
46
|
+
But since so many apps are waiting on IO from DBs, etc., they can utilize threads
|
47
|
+
to make better use of the process.
|
48
|
+
|
49
|
+
The rule of thumb is you never want processes that are pegged all the time. This
|
50
|
+
means that there is more work to do that the process can get through. On the other
|
51
|
+
hand, if you have processes that sit around doing nothing, then they're just eating
|
52
|
+
up resources.
|
53
|
+
|
54
|
+
Watching your CPU utilization over time and aim for about 70% on average. This means
|
55
|
+
you've got capacity still but aren't starving threads.
|
56
|
+
|
57
|
+
## Daemonizing
|
58
|
+
|
59
|
+
I prefer to not daemonize my servers and use something like `runit` or `upstrart` to
|
60
|
+
monitor them as child processes. This gives them fast response to crashes and
|
61
|
+
makes it easy to figure out what is going on. Additionally, unlike `unicorn`,
|
62
|
+
puma does not require daemonization to do zero-downtime restarts.
|
63
|
+
|
64
|
+
I see people using daemonization because they start puma directly via capistrano
|
65
|
+
task and thus want it to live on past the `cap deploy`. To this people I said:
|
66
|
+
You need to be using a process monitor. Nothing is making sure puma stays up in
|
67
|
+
this scenario! You're just waiting for something weird to happen, puma to die,
|
68
|
+
and to get paged at 3am. Do yourself a favor, at least the process monitoring
|
69
|
+
your OS comes with, be it `sysvinit`, `upstart`, or `systemd`. Or branch out
|
70
|
+
and use `runit` or hell, even `monit`.
|
71
|
+
|
72
|
+
## Restarting
|
73
|
+
|
74
|
+
You probably will want to deploy some new code at some point, and you'd like
|
75
|
+
puma to start running that new code. Minimizing the amount of time the server
|
76
|
+
is unavailable would be nice as well. Here's how to do it:
|
77
|
+
|
78
|
+
1. Don't use `preload!`. This dirties the master process and means it will have
|
79
|
+
to shutdown all the workers and re-exec itself to get your new code, which means
|
80
|
+
much higher waiting around for things to load.
|
81
|
+
|
82
|
+
1. Use `prune_bundler`. This makes it so that the cluster master will detach itself
|
83
|
+
from a Bundler context on start. This allows the cluster workers to load your app
|
84
|
+
and start a brand new Bundler context within the worker only. This means your
|
85
|
+
master remains pristine and can live on between new releases of your code.
|
86
|
+
|
87
|
+
1. Use phased-restart (`SIGUSR1` or `pumactl phased-restart`). This tells the master
|
88
|
+
to kill off one worker at a time and restart them in your new code. This minimizes
|
89
|
+
downtime and staggers the restart nicely. **WARNING** This means that both your
|
90
|
+
old code and your new code will be running concurrently. Most deployment solutions
|
91
|
+
already cause that, but it's worth warning you about it again. Be careful with your
|
92
|
+
migrations, etc!
|
@@ -0,0 +1,17 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem "hoe"
|
4
|
+
gem "hoe-git"
|
5
|
+
gem "hoe-ignore"
|
6
|
+
gem "rdoc"
|
7
|
+
gem "rake-compiler"
|
8
|
+
gem "rack"
|
9
|
+
|
10
|
+
gem 'minitest', '~> 4.0'
|
11
|
+
|
12
|
+
gem "jruby-openssl", :platform => "jruby"
|
13
|
+
|
14
|
+
platforms :rbx do
|
15
|
+
gem 'rubysl', '~> 2.0'
|
16
|
+
end
|
17
|
+
|