steamcannon-thin 1.2.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. data/CHANGELOG +288 -0
  2. data/COPYING +18 -0
  3. data/README +69 -0
  4. data/Rakefile +44 -0
  5. data/benchmark/abc +51 -0
  6. data/benchmark/benchmarker.rb +80 -0
  7. data/benchmark/runner +82 -0
  8. data/bin/thin +6 -0
  9. data/example/adapter.rb +32 -0
  10. data/example/async_app.ru +126 -0
  11. data/example/async_chat.ru +247 -0
  12. data/example/async_tailer.ru +100 -0
  13. data/example/config.ru +22 -0
  14. data/example/monit_sockets +20 -0
  15. data/example/monit_unixsock +20 -0
  16. data/example/myapp.rb +1 -0
  17. data/example/ramaze.ru +12 -0
  18. data/example/thin.god +80 -0
  19. data/example/thin_solaris_smf.erb +36 -0
  20. data/example/thin_solaris_smf.readme.txt +150 -0
  21. data/example/vlad.rake +64 -0
  22. data/ext/thin_parser/common.rl +55 -0
  23. data/ext/thin_parser/ext_help.h +14 -0
  24. data/ext/thin_parser/extconf.rb +6 -0
  25. data/ext/thin_parser/parser.c +1249 -0
  26. data/ext/thin_parser/parser.h +49 -0
  27. data/ext/thin_parser/parser.rl +157 -0
  28. data/ext/thin_parser/thin.c +436 -0
  29. data/lib/rack/adapter/loader.rb +91 -0
  30. data/lib/rack/adapter/rails.rb +183 -0
  31. data/lib/thin.rb +56 -0
  32. data/lib/thin/backends/base.rb +149 -0
  33. data/lib/thin/backends/swiftiply_client.rb +56 -0
  34. data/lib/thin/backends/tcp_server.rb +29 -0
  35. data/lib/thin/backends/unix_server.rb +51 -0
  36. data/lib/thin/command.rb +53 -0
  37. data/lib/thin/connection.rb +224 -0
  38. data/lib/thin/controllers/cluster.rb +178 -0
  39. data/lib/thin/controllers/controller.rb +188 -0
  40. data/lib/thin/controllers/service.rb +75 -0
  41. data/lib/thin/controllers/service.sh.erb +39 -0
  42. data/lib/thin/daemonizing.rb +180 -0
  43. data/lib/thin/headers.rb +39 -0
  44. data/lib/thin/logging.rb +54 -0
  45. data/lib/thin/request.rb +156 -0
  46. data/lib/thin/response.rb +101 -0
  47. data/lib/thin/runner.rb +220 -0
  48. data/lib/thin/server.rb +253 -0
  49. data/lib/thin/stats.html.erb +216 -0
  50. data/lib/thin/stats.rb +52 -0
  51. data/lib/thin/statuses.rb +43 -0
  52. data/lib/thin/version.rb +32 -0
  53. data/lib/thin_parser.so +0 -0
  54. data/spec/backends/swiftiply_client_spec.rb +66 -0
  55. data/spec/backends/tcp_server_spec.rb +33 -0
  56. data/spec/backends/unix_server_spec.rb +37 -0
  57. data/spec/command_spec.rb +25 -0
  58. data/spec/configs/cluster.yml +9 -0
  59. data/spec/configs/single.yml +9 -0
  60. data/spec/connection_spec.rb +106 -0
  61. data/spec/controllers/cluster_spec.rb +267 -0
  62. data/spec/controllers/controller_spec.rb +129 -0
  63. data/spec/controllers/service_spec.rb +50 -0
  64. data/spec/daemonizing_spec.rb +196 -0
  65. data/spec/headers_spec.rb +40 -0
  66. data/spec/logging_spec.rb +46 -0
  67. data/spec/perf/request_perf_spec.rb +50 -0
  68. data/spec/perf/response_perf_spec.rb +19 -0
  69. data/spec/perf/server_perf_spec.rb +39 -0
  70. data/spec/rack/loader_spec.rb +42 -0
  71. data/spec/rack/rails_adapter_spec.rb +173 -0
  72. data/spec/rails_app/app/controllers/application.rb +10 -0
  73. data/spec/rails_app/app/controllers/simple_controller.rb +19 -0
  74. data/spec/rails_app/app/helpers/application_helper.rb +3 -0
  75. data/spec/rails_app/app/views/simple/index.html.erb +15 -0
  76. data/spec/rails_app/config/boot.rb +109 -0
  77. data/spec/rails_app/config/environment.rb +64 -0
  78. data/spec/rails_app/config/environments/development.rb +18 -0
  79. data/spec/rails_app/config/environments/production.rb +19 -0
  80. data/spec/rails_app/config/environments/test.rb +22 -0
  81. data/spec/rails_app/config/initializers/inflections.rb +10 -0
  82. data/spec/rails_app/config/initializers/mime_types.rb +5 -0
  83. data/spec/rails_app/config/routes.rb +35 -0
  84. data/spec/rails_app/public/404.html +30 -0
  85. data/spec/rails_app/public/422.html +30 -0
  86. data/spec/rails_app/public/500.html +30 -0
  87. data/spec/rails_app/public/dispatch.cgi +10 -0
  88. data/spec/rails_app/public/dispatch.fcgi +24 -0
  89. data/spec/rails_app/public/dispatch.rb +10 -0
  90. data/spec/rails_app/public/favicon.ico +0 -0
  91. data/spec/rails_app/public/images/rails.png +0 -0
  92. data/spec/rails_app/public/index.html +277 -0
  93. data/spec/rails_app/public/javascripts/application.js +2 -0
  94. data/spec/rails_app/public/javascripts/controls.js +963 -0
  95. data/spec/rails_app/public/javascripts/dragdrop.js +972 -0
  96. data/spec/rails_app/public/javascripts/effects.js +1120 -0
  97. data/spec/rails_app/public/javascripts/prototype.js +4225 -0
  98. data/spec/rails_app/public/robots.txt +5 -0
  99. data/spec/rails_app/script/about +3 -0
  100. data/spec/rails_app/script/console +3 -0
  101. data/spec/rails_app/script/destroy +3 -0
  102. data/spec/rails_app/script/generate +3 -0
  103. data/spec/rails_app/script/performance/benchmarker +3 -0
  104. data/spec/rails_app/script/performance/profiler +3 -0
  105. data/spec/rails_app/script/performance/request +3 -0
  106. data/spec/rails_app/script/plugin +3 -0
  107. data/spec/rails_app/script/process/inspector +3 -0
  108. data/spec/rails_app/script/process/reaper +3 -0
  109. data/spec/rails_app/script/process/spawner +3 -0
  110. data/spec/rails_app/script/runner +3 -0
  111. data/spec/rails_app/script/server +3 -0
  112. data/spec/request/mongrel_spec.rb +39 -0
  113. data/spec/request/parser_spec.rb +254 -0
  114. data/spec/request/persistent_spec.rb +35 -0
  115. data/spec/request/processing_spec.rb +50 -0
  116. data/spec/response_spec.rb +91 -0
  117. data/spec/runner_spec.rb +168 -0
  118. data/spec/server/builder_spec.rb +44 -0
  119. data/spec/server/pipelining_spec.rb +110 -0
  120. data/spec/server/robustness_spec.rb +34 -0
  121. data/spec/server/stopping_spec.rb +55 -0
  122. data/spec/server/swiftiply.yml +6 -0
  123. data/spec/server/swiftiply_spec.rb +32 -0
  124. data/spec/server/tcp_spec.rb +57 -0
  125. data/spec/server/threaded_spec.rb +27 -0
  126. data/spec/server/unix_socket_spec.rb +26 -0
  127. data/spec/server_spec.rb +100 -0
  128. data/spec/spec_helper.rb +220 -0
  129. data/tasks/announce.rake +22 -0
  130. data/tasks/deploy.rake +13 -0
  131. data/tasks/email.erb +30 -0
  132. data/tasks/gem.rake +66 -0
  133. data/tasks/rdoc.rake +25 -0
  134. data/tasks/site.rake +15 -0
  135. data/tasks/spec.rake +43 -0
  136. data/tasks/stats.rake +28 -0
  137. metadata +251 -0
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env rackup -s thin
2
+ #
3
+ # async_tailer.ru
4
+ # raggi/thin
5
+ #
6
+ # Tested with 150 spawned tails on OS X
7
+ #
8
+ # Created by James Tucker on 2008-06-18.
9
+ # Copyright 2008 James Tucker <raggi@rubyforge.org>.
10
+
11
+ # Uncomment if appropriate for you..
12
+ # EM.epoll
13
+ # EM.kqueue
14
+
15
+ class DeferrableBody
16
+ include EventMachine::Deferrable
17
+
18
+ def initialize
19
+ @queue = []
20
+ # make sure to flush out the queue before closing the connection
21
+ callback{
22
+ until @queue.empty?
23
+ @queue.shift.each{|chunk| @body_callback.call(chunk) }
24
+ end
25
+ }
26
+ end
27
+
28
+ def schedule_dequeue
29
+ return unless @body_callback
30
+ EventMachine::next_tick do
31
+ next unless body = @queue.shift
32
+ body.each do |chunk|
33
+ @body_callback.call(chunk)
34
+ end
35
+ schedule_dequeue unless @queue.empty?
36
+ end
37
+ end
38
+
39
+ def call(body)
40
+ @queue << body
41
+ schedule_dequeue
42
+ end
43
+
44
+ def each &blk
45
+ @body_callback = blk
46
+ schedule_dequeue
47
+ end
48
+
49
+ end
50
+
51
+ module TailRenderer
52
+ attr_accessor :callback
53
+
54
+ def receive_data(data)
55
+ @callback.call([data])
56
+ end
57
+
58
+ def unbind
59
+ @callback.succeed
60
+ end
61
+ end
62
+
63
+ class AsyncTailer
64
+
65
+ AsyncResponse = [-1, {}, []].freeze
66
+
67
+ def call(env)
68
+
69
+ body = DeferrableBody.new
70
+
71
+ EventMachine::next_tick do
72
+
73
+ env['async.callback'].call [200, {'Content-Type' => 'text/html'}, body]
74
+
75
+ body.call ["<h1>Async Tailer</h1><pre>"]
76
+
77
+ end
78
+
79
+ EventMachine::popen('tail -f /var/log/system.log', TailRenderer) do |t|
80
+
81
+ t.callback = body
82
+
83
+ # If for some reason we 'complete' body, close the tail.
84
+ body.callback do
85
+ t.close_connection
86
+ end
87
+
88
+ # If for some reason the client disconnects, close the tail.
89
+ body.errback do
90
+ t.close_connection
91
+ end
92
+
93
+ end
94
+
95
+ AsyncResponse
96
+ end
97
+
98
+ end
99
+
100
+ run AsyncTailer.new
data/example/config.ru ADDED
@@ -0,0 +1,22 @@
1
+ # Run with: rackup -s thin
2
+ # then browse to http://localhost:9292
3
+ # Or with: thin start -R config.ru
4
+ # then browse to http://localhost:3000
5
+ #
6
+ # Check Rack::Builder doc for more details on this file format:
7
+ # http://rack.rubyforge.org/doc/classes/Rack/Builder.html
8
+ require 'thin'
9
+
10
+ app = proc do |env|
11
+ # Response body has to respond to each and yield strings
12
+ # See Rack specs for more info: http://rack.rubyforge.org/doc/files/SPEC.html
13
+ body = ['hi!']
14
+
15
+ [
16
+ 200, # Status code
17
+ { 'Content-Type' => 'text/html' }, # Reponse headers
18
+ body # Body of the response
19
+ ]
20
+ end
21
+
22
+ run app
@@ -0,0 +1,20 @@
1
+ check process blog1
2
+ with pidfile /u/apps/blog/shared/pids/thin.14000.pid
3
+ start program = "/usr/local/bin/ruby /usr/local/bin/thin start -d -e production -u nobody -g nobody -p 14000 -a 127.0.0.1 -P tmp/pids/thin.14000.pid -c /u/apps/blog/current"
4
+ stop program = "/usr/local/bin/ruby /usr/local/bin/thin stop -P /u/apps/blog/shared/pids/thin.14000.pid"
5
+ if totalmem > 90.0 MB for 5 cycles then restart
6
+ if failed port 14000 then restart
7
+ if cpu usage > 95% for 3 cycles then restart
8
+ if 5 restarts within 5 cycles then timeout
9
+ group blog
10
+
11
+ check process blog2
12
+ with pidfile /u/apps/blog/shared/pids/thin.14001.pid
13
+ start program = "/usr/local/bin/ruby /usr/local/bin/thin start -d -e production -u nobody -g nobody -p 14001 -a 127.0.0.1 -P tmp/pids/thin.14001.pid -c /u/apps/blog/current"
14
+ stop program = "/usr/local/bin/ruby /usr/local/bin/thin stop -P /u/apps/blog/shared/pids/thin.14001.pid"
15
+ if totalmem > 90.0 MB for 5 cycles then restart
16
+ if failed port 14001 then restart
17
+ if cpu usage > 95% for 3 cycles then restart
18
+ if 5 restarts within 5 cycles then timeout
19
+ group blog
20
+
@@ -0,0 +1,20 @@
1
+ check process blog1
2
+ with pidfile /u/apps/blog/shared/pids/thin.1.pid
3
+ start program = "/usr/local/bin/ruby /usr/local/bin/thin start -d -e production -S /u/apps/blog/shared/pids/thin.1.sock -P tmp/pids/thin.1.pid -c /u/apps/blog/current"
4
+ stop program = "/usr/local/bin/ruby /usr/local/bin/thin stop -P /u/apps/blog/shared/pids/thin.1.pid"
5
+ if totalmem > 90.0 MB for 5 cycles then restart
6
+ if failed unixsocket /u/apps/blog/shared/pids/thin.1.sock then restart
7
+ if cpu usage > 95% for 3 cycles then restart
8
+ if 5 restarts within 5 cycles then timeout
9
+ group blog
10
+
11
+ check process blog2
12
+ with pidfile /u/apps/blog/shared/pids/thin.2.pid
13
+ start program = "/usr/local/bin/ruby /usr/local/bin/thin start -d -e production -S /u/apps/blog/shared/pids/thin.2.sock -P tmp/pids/thin.2.pid -c /u/apps/blog/current"
14
+ stop program = "/usr/local/bin/ruby /usr/local/bin/thin stop -P /u/apps/blog/shared/pids/thin.2.pid"
15
+ if totalmem > 90.0 MB for 5 cycles then restart
16
+ if failed unixsocket /u/apps/blog/shared/pids/thin.2.sock then restart
17
+ if cpu usage > 95% for 3 cycles then restart
18
+ if 5 restarts within 5 cycles then timeout
19
+ group blog
20
+
data/example/myapp.rb ADDED
@@ -0,0 +1 @@
1
+ Myapp = lambda { |env| [200, {}, 'this is my app!'] }
data/example/ramaze.ru ADDED
@@ -0,0 +1,12 @@
1
+ # Ramaze Rackup config file.
2
+ # by tmm1
3
+ # Use with --rackup option:
4
+ #
5
+ # thin start -r ramaze.ru
6
+ #
7
+ require 'start'
8
+
9
+ Ramaze.trait[:essentials].delete Ramaze::Adapter
10
+ Ramaze.start :force => true
11
+
12
+ run Ramaze::Adapter::Base
data/example/thin.god ADDED
@@ -0,0 +1,80 @@
1
+ # == God config file
2
+ # http://god.rubyforge.org/
3
+ # Authors: Gump and michael@glauche.de
4
+ #
5
+ # Config file for god that configures watches for each instance of a thin server for
6
+ # each thin configuration file found in /etc/thin.
7
+ # In order to get it working on Ubuntu, I had to make a change to god as noted at
8
+ # the following blog:
9
+ # http://blog.alexgirard.com/ruby-one-line-to-save-god/
10
+ #
11
+ require 'yaml'
12
+
13
+ config_path = "/etc/thin"
14
+
15
+ Dir[config_path + "/*.yml"].each do |file|
16
+ config = YAML.load_file(file)
17
+ num_servers = config["servers"] ||= 1
18
+
19
+ (0...num_servers).each do |i|
20
+ # UNIX socket cluster use number 0 to 2 (for 3 servers)
21
+ # and tcp cluster use port number 3000 to 3002.
22
+ number = config['socket'] ? i : (config['port'] + i)
23
+
24
+ God.watch do |w|
25
+ w.group = "thin-" + File.basename(file, ".yml")
26
+ w.name = w.group + "-#{number}"
27
+
28
+ w.interval = 30.seconds
29
+
30
+ w.uid = config["user"]
31
+ w.gid = config["group"]
32
+
33
+ w.start = "thin start -C #{file} -o #{number}"
34
+ w.start_grace = 10.seconds
35
+
36
+ w.stop = "thin stop -C #{file} -o #{number}"
37
+ w.stop_grace = 10.seconds
38
+
39
+ w.restart = "thin restart -C #{file} -o #{number}"
40
+
41
+ pid_path = config["chdir"] + "/" + config["pid"]
42
+ ext = File.extname(pid_path)
43
+
44
+ w.pid_file = pid_path.gsub(/#{ext}$/, ".#{number}#{ext}")
45
+
46
+ w.behavior(:clean_pid_file)
47
+
48
+ w.start_if do |start|
49
+ start.condition(:process_running) do |c|
50
+ c.interval = 5.seconds
51
+ c.running = false
52
+ end
53
+ end
54
+
55
+ w.restart_if do |restart|
56
+ restart.condition(:memory_usage) do |c|
57
+ c.above = 150.megabytes
58
+ c.times = [3,5] # 3 out of 5 intervals
59
+ end
60
+
61
+ restart.condition(:cpu_usage) do |c|
62
+ c.above = 50.percent
63
+ c.times = 5
64
+ end
65
+ end
66
+
67
+ w.lifecycle do |on|
68
+ on.condition(:flapping) do |c|
69
+ c.to_state = [:start, :restart]
70
+ c.times = 5
71
+ c.within = 5.minutes
72
+ c.transition = :unmonitored
73
+ c.retry_in = 10.minutes
74
+ c.retry_times = 5
75
+ c.retry_within = 2.hours
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,36 @@
1
+ <?xml version='1.0'?>
2
+ <!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>
3
+ <service_bundle type='manifest' name='thin/<%= service_name %>-production'>
4
+ <service name='network/thin/<%= service_name %>-production' type='service' version='0'>
5
+ <!-- Dependancies for all Thin servers. -->
6
+ <dependency name='fs' grouping='require_all' restart_on='none' type='service'>
7
+ <service_fmri value='svc:/system/filesystem/local'/>
8
+ </dependency>
9
+ <dependency name='net' grouping='require_all' restart_on='none' type='service'>
10
+ <service_fmri value='svc:/network/loopback'/>
11
+ <!-- uncomment the following line if you are on an L+ Accelerator since /home is mounted through nfs -->
12
+ <!--<service_fmri value='svc:/network/nfs/client'/>-->
13
+ </dependency>
14
+ <% 0.upto(thin_max_instances - 1) do |instance| %>
15
+ <!-- instance names can't start with digits. Bummer. -->
16
+ <instance name='i_<%= instance.to_s %>' enabled='false'>
17
+ <!-- Cause the multi-user milestone to bring these services up -->
18
+ <dependent name='<%= service_name %>_<%= instance.to_s %>_multi-user' restart_on='none' grouping='optional_all'>
19
+ <service_fmri value='svc:/milestone/multi-user'/>
20
+ </dependent>
21
+ <exec_method name='start' type='method'
22
+ exec='/opt/csw/bin/thin -C config/thin.yml --only <%= instance.to_s %> start'
23
+ timeout_seconds='10'>
24
+ <method_context working_directory='<%= working_directory %>'>
25
+ <method_credential user='<%= user %>' group='<%= group %>' />
26
+ <method_environment>
27
+ <envvar name='PATH' value='/usr/bin:/bin:/opt/csw/bin' />
28
+ </method_environment>
29
+ </method_context>
30
+ </exec_method>
31
+ <exec_method name='stop' type='method' exec=':kill' timeout_seconds='10' />
32
+ </instance>
33
+ <% end %>
34
+ </service>
35
+ </service_bundle>
36
+
@@ -0,0 +1,150 @@
1
+ Using Thin with Solaris' SMF Monitoring Framework
2
+ - - - - - - - - - - - - - - - - - - - - - - - - -
3
+
4
+ Solaris uses the Service Management Framework (SMF) at the OS level to manage, monitor, and restart long running processes. This replaces init scripts, and tools like monit and god.
5
+
6
+ The sample XML file (thin_solaris_smf.erb) is an example SMF manifest which I use on a Joyent accelerator which runs on OpenSolaris.
7
+
8
+ This setup will:
9
+
10
+ - ensure the right dependencies are loaded
11
+ - start n instances of Thin, and monitor each individually. If any single one dies it will be restarted instantly (test it by killing a single thin instance and it will be back alive before you can type 'ps -ef').
12
+
13
+ This is better than using clustering since if you start the cluster with SMF it will only notice a problem and restart individual Thin's if ALL of them are dead, at which point it will restart the whole cluster. This approach makes sure that all of your Thins start together and are monitored and managed independant of each other. This problem likely exists if you are using god or monit to monitor only the start of the master cluster, and don't then monitor the individual processes started.
14
+
15
+ This example is in .erb format instead of plain XML since I dynamically generate this file as part of a Capistrano deployment. In my deploy.rb file I define the variables found in this erb. Of course you don't need to use this with Capistrano. Just replace the few ERB variables from the xml file, change its extension, and load that directly in Solaris if you prefer.
16
+
17
+ Here are some examples for usage to get you started with Capistrano, and Thin:
18
+
19
+ FILE : config/deploy.rb
20
+ --
21
+
22
+ require 'config/accelerator/accelerator_tasks'
23
+
24
+ set :application, "yourapp"
25
+ set :svcadm_bin, "/usr/sbin/svcadm"
26
+ set :svccfg_bin, "/usr/sbin/svccfg"
27
+ set :svcs_bin, "/usr/bin/svcs"
28
+
29
+ # gets the list of remote service SMF names that we need to start
30
+ # like (depending on thin_max_instances settings):
31
+ # svc:/network/thin/yourapp-production:i_0
32
+ # svc:/network/thin/yourapp-production:i_1
33
+ # svc:/network/thin/yourapp-production:i_2
34
+ set :service_list, "`svcs -H -o FMRI svc:network/thin/#{application}-production`"
35
+
36
+ # how many Thin instances should be setup to run?
37
+ # this affects the generated thin smf file, and the nginx vhost conf
38
+ # need to re-run setup for thin smf and nginx vhost conf when changed
39
+ set :thin_max_instances, 3
40
+
41
+ # OVERRIDE STANDARD TASKS
42
+ desc "Restart the entire application"
43
+ deploy.task :restart do
44
+ accelerator.thin.restart
45
+ accelerator.nginx.restart
46
+ end
47
+
48
+ desc "Start the entire application"
49
+ deploy.task :start do
50
+ accelerator.thin.restart
51
+ accelerator.nginx.restart
52
+ end
53
+
54
+ desc "Stop the entire application"
55
+ deploy.task :stop do
56
+ accelerator.thin.disable
57
+ accelerator.nginx.disable
58
+ end
59
+
60
+
61
+ FILE : config/accelerator/accelerator_tasks.rb
62
+ --
63
+
64
+ desc "Create and deploy Thin SMF config"
65
+ task :create_thin_smf, :roles => :app do
66
+ service_name = application
67
+ working_directory = current_path
68
+ template = File.read("config/accelerator/thin_solaris_smf.erb")
69
+ buffer = ERB.new(template).result(binding)
70
+ put buffer, "#{shared_path}/#{application}-thin-smf.xml"
71
+ sudo "#{svccfg_bin} import #{shared_path}/#{application}-thin-smf.xml"
72
+ end
73
+
74
+ desc "Delete Thin SMF config"
75
+ task :delete_thin_smf, :roles => :app do
76
+ accelerator.thin.disable
77
+ sudo "#{svccfg_bin} delete /network/thin/#{application}-production"
78
+ end
79
+
80
+ desc "Show all SMF services"
81
+ task :svcs do
82
+ run "#{svcs_bin} -a" do |ch, st, data|
83
+ puts data
84
+ end
85
+ end
86
+
87
+ desc "Shows all non-functional SMF services"
88
+ task :svcs_broken do
89
+ run "#{svcs_bin} -vx" do |ch, st, data|
90
+ puts data
91
+ end
92
+ end
93
+
94
+
95
+ namespace :thin do
96
+
97
+ desc "Disable all Thin servers"
98
+ task :disable, :roles => :app do
99
+ # temporarily disable, until next reboot (-t)
100
+ sudo "#{svcadm_bin} disable -t #{service_list}"
101
+ end
102
+
103
+ desc "Enable all Thin servers"
104
+ task :enable, :roles => :app do
105
+ # start the app with all recursive dependencies
106
+ sudo "#{svcadm_bin} enable -r #{service_list}"
107
+ end
108
+
109
+ desc "Restart all Thin servers"
110
+ task :restart, :roles => :app do
111
+ # svcadm restart doesn't seem to work right, so we'll brute force it
112
+ disable
113
+ enable
114
+ end
115
+
116
+ end # namespace thin
117
+
118
+
119
+ FILE : config/thin.yml
120
+ --
121
+
122
+ ---
123
+ pid: tmp/pids/thin.pid
124
+ socket: /tmp/thin.sock
125
+ log: log/thin.log
126
+ max_conns: 1024
127
+ timeout: 30
128
+ chdir: /your/app/dir/rails/root
129
+ environment: production
130
+ max_persistent_conns: 512
131
+ daemonize: true
132
+ servers: 3
133
+
134
+
135
+ FILE : config/accelerator/thin_solaris_smf.erb
136
+ --
137
+ This is of course an example. It works for me, but YMMV
138
+
139
+ You may need to change this line to match your environment and config:
140
+ exec='/opt/csw/bin/thin -C config/thin.yml --only <%= instance.to_s %> start'
141
+
142
+
143
+ CONTRIBUTE:
144
+
145
+ If you see problems or enhancements for this approach please send me an email at glenn [at] rempe dot us. Sadly, I won't be able to provide support for this example as time and my limited Solaris admin skills won't allow.
146
+
147
+ Cheers,
148
+
149
+ Glenn Rempe
150
+ 2008/03/20