mongrel_service 0.3.4-x86-mingw32

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,70 @@
1
+ '#--
2
+ '# Copyright (c) 2006-2007 Luis Lavena, Multimedia systems
3
+ '#
4
+ '# This source code is released under the MIT License.
5
+ '# See MIT-LICENSE file for details
6
+ '#++
7
+
8
+ #if __FB_VERSION__ < "0.17"
9
+ #error ServiceFB is designed to compile with FreeBASIC version "0.17"
10
+ #else
11
+
12
+ #ifndef __FB_WIN32__
13
+ #error Platform unsupported. Compiling ServiceFB requires Windows platform.
14
+ #else
15
+
16
+ #ifndef __ServiceFB_Utils_bi__
17
+ #define __ServiceFB_Utils_bi__
18
+
19
+ #include once "win/psapi.bi"
20
+ #include once "win/tlhelp32.bi"
21
+
22
+ namespace fb
23
+ namespace svc
24
+ namespace utils '# fb.svc.utils
25
+ '# use this to determine (using select case maybe?) the
26
+ '# mode which the service was invoked.
27
+ enum ServiceRunMode
28
+ RunAsUnknown = 0
29
+ RunAsService
30
+ RunAsManager
31
+ RunAsConsole
32
+ end enum
33
+
34
+
35
+ '# ServiceController type (object)
36
+ '# this is a helper object in case you want to implement
37
+ '# console mode (command line testing/debugging) and management (install/remove/control)
38
+ '# to your services, all from the same executable
39
+ type ServiceController
40
+ '# ctor/dtor()
41
+ declare constructor()
42
+ declare constructor(byref as string)
43
+ declare constructor(byref as string, byref as string)
44
+ declare constructor(byref as string, byref as string, byref as string)
45
+ declare destructor()
46
+
47
+ '# methods (public)
48
+ declare sub Banner()
49
+ declare function RunMode() as ServiceRunMode
50
+ declare sub Manage()
51
+ declare sub Manage(byref as ServiceProcess)
52
+ declare sub Console()
53
+ declare sub Console(byref as ServiceProcess)
54
+
55
+ '# properties (public)
56
+ '# use these properties for shwoing information on console/manager mode
57
+ '# as banner.
58
+ '# Product, version
59
+ '# copyright
60
+ product as string
61
+ version as string
62
+ copyright as string
63
+ end type
64
+ end namespace '# fb.svc.utils
65
+ end namespace '# fb.svc
66
+ end namespace '# fb
67
+
68
+ #endif '# __ServiceFB_bi__
69
+ #endif '# __FB_WIN32__
70
+ #endif '# __FB_VERSION__
@@ -0,0 +1,50 @@
1
+ '#--
2
+ '# Copyright (c) 2006-2007 Luis Lavena, Multimedia systems
3
+ '#
4
+ '# This source code is released under the MIT License.
5
+ '# See MIT-LICENSE file for details
6
+ '#++
7
+
8
+ '##################################################################
9
+ '#
10
+ '# DO NOT INCLUDE THIS FILE DIRECTLY!
11
+ '# it is used internaly by ServiceFB
12
+ '# use ServiceFB.bi instead
13
+ '#
14
+ '##################################################################
15
+
16
+ namespace fb
17
+ namespace svc
18
+ '# now due references locking, I needed a constructor and destructor for
19
+ '# the namespace to garantee everything is cleaned up on termination of the process
20
+ declare sub _initialize() constructor
21
+ declare sub _terminate() destructor
22
+
23
+ '# global service procedures (private)
24
+ declare sub _main(byval as DWORD, byval as LPSTR ptr)
25
+ declare function _control_ex(byval as DWORD, byval as DWORD, byval as LPVOID, byval as LPVOID) as DWORD
26
+ declare sub _run()
27
+
28
+ '# global references helper
29
+ declare function _add_to_references(byref as ServiceProcess) as integer
30
+ declare function _find_in_references(byref as string) as ServiceProcess ptr
31
+
32
+ '# command line builder (helper)
33
+ '# this is used to gather information about:
34
+ '# mode (if present)
35
+ '# valid service name (after lookup in the table)
36
+ '# command line to be passed to service
37
+ declare sub _build_commandline(byref as string, byref as string, byref as string)
38
+
39
+ '# I started this as simple, unique service served from one process
40
+ '# but the idea of share the same process space (and reduce resources use) was good.
41
+ '# to do that, I needed a references table (similar to service_table, but we will
42
+ '# hold the ServiceProcess registered by ServiceHost (the multi services host).
43
+ '# also, I needed a locking mechanism to avoid problems of two calls changing the table
44
+ '# at the same time.
45
+ extern _svc_references as ServiceProcess ptr ptr
46
+ extern _svc_references_count as integer
47
+ extern _svc_references_lock as any ptr
48
+ end namespace '# fb.svc
49
+ end namespace '# fb
50
+
@@ -0,0 +1,49 @@
1
+ '#--
2
+ '# Copyright (c) 2006-2007 Luis Lavena, Multimedia systems
3
+ '#
4
+ '# This source code is released under the MIT License.
5
+ '# See MIT-LICENSE file for details
6
+ '#++
7
+
8
+ '##################################################################
9
+ '#
10
+ '# DO NOT INCLUDE THIS FILE DIRECTLY!
11
+ '# it is used internaly by ServiceFB
12
+ '# use ServiceFB_Utils.bi instead
13
+ '#
14
+ '##################################################################
15
+
16
+ namespace fb
17
+ namespace svc
18
+ namespace utils '# fb.svc.utils
19
+ '# console_handler is used to get feedback form keyboard and allow
20
+ '# shutdown of service using Ctrl+C / Ctrl+Break from keyboard
21
+ declare function _console_handler(byval as DWORD) as BOOL
22
+
23
+ '# helper private subs used to list the services and their descriptions
24
+ '# in _svc_references
25
+ declare sub _list_references()
26
+
27
+ '# internals functions used to get Parent PID and Process Name
28
+ '# using this we automatically determine if the service was started by SCM
29
+ '# or by the user, from commandline or from explorer
30
+ declare function _parent_pid(byval as uinteger) as uinteger
31
+ declare function _process_name(byval as uinteger) as string
32
+ declare function _process_name_dyn_psapi(byval as uinteger) as string
33
+ declare function _show_error() as string
34
+
35
+ '# InStrRev (authored by ikkejw @ freebasic forums)
36
+ '# http://www.freebasic.net/forum/viewtopic.php?p=49315#49315
37
+ declare function InStrRev(byval as uinteger = 0, byref as string, byref as string) as uinteger
38
+
39
+ '# use a signal (condition) in the console mode to know
40
+ '# when the service should be stopped.
41
+ '# the Console() main loop will wait for it, and the console_handler
42
+ '# will raise in case Ctrl+C / Ctrl+Break or other events are
43
+ '# received.
44
+ extern _svc_stop_signal as any ptr
45
+ extern _svc_in_console as ServiceProcess ptr
46
+ extern _svc_in_console_stop_flag as BOOL
47
+ end namespace '# fb.svc.utils
48
+ end namespace '# fb.svc
49
+ end namespace '# fb
@@ -0,0 +1,211 @@
1
+ require 'gem_plugin'
2
+ require 'mongrel'
3
+ require 'mongrel/rails'
4
+ require 'rbconfig'
5
+ require 'fileutils'
6
+
7
+ module Service
8
+ class Install < GemPlugin::Plugin "/commands"
9
+ include Mongrel::Command::Base
10
+
11
+ def configure
12
+ options [
13
+ ['-N', '--name SVC_NAME', "Required name for the service to be registered/installed.", :@svc_name, nil],
14
+ ['-D', '--display SVC_DISPLAY', "Adjust the display name of the service.", :@svc_display, nil],
15
+ ["-e", "--environment ENV", "Rails environment to run as", :@environment, ENV['RAILS_ENV'] || "development"],
16
+ ['-p', '--port PORT', "Which port to bind to", :@port, 3000],
17
+ ['-a', '--address ADDR', "Address to bind to", :@address, "0.0.0.0"],
18
+ ['-l', '--log FILE', "Where to write log messages", :@log_file, "log/mongrel.log"],
19
+ ['-P', '--pid FILE', "Where to write the PID", :@pid_file, "log/mongrel.pid"],
20
+ ['-n', '--num-procs INT', "Number of processors active before clients denied", :@num_procs, 1024],
21
+ ['-t', '--timeout TIME', "Timeout all requests after 100th seconds time", :@timeout, 0],
22
+ ['-m', '--mime PATH', "A YAML file that lists additional MIME types", :@mime_map, nil],
23
+ ['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, Dir.pwd],
24
+ ['-r', '--root PATH', "Set the document root (default 'public')", :@docroot, "public"],
25
+ ['-B', '--debug', "Enable debugging mode", :@debug, false],
26
+ ['-C', '--config PATH', "Use a config file", :@config_file, nil],
27
+ ['-S', '--script PATH', "Load the given file as an extra config script.", :@config_script, nil],
28
+ ['', '--prefix PATH', "URL prefix for Rails app", :@prefix, nil]
29
+ ]
30
+ end
31
+
32
+ # When we validate the options, we need to make sure the --root is actually RAILS_ROOT
33
+ # of the rails application we wanted to serve, because later "as service" no error
34
+ # show to trace this.
35
+ def validate
36
+ # TODO: investigate why Win32::Service interfere with gem_plugin
37
+ gem 'win32-service', '>= 0.5.2', '< 0.6.0'
38
+ require 'win32/service'
39
+
40
+ @cwd = File.expand_path(@cwd)
41
+ valid_dir? @cwd, "Invalid path to change to: #@cwd"
42
+
43
+ # change there to start, then we'll have to come back after daemonize
44
+ Dir.chdir(@cwd)
45
+
46
+ # start with the premise of app really exist.
47
+ app_exist = true
48
+ %w{app config log}.each do |path|
49
+ if !File.directory?(File.join(@cwd, path))
50
+ app_exist = false
51
+ break
52
+ end
53
+ end
54
+
55
+ valid?(@prefix[0].chr == "/" && @prefix[-1].chr != "/", "Prefix must begin with / and not end in /") if @prefix
56
+
57
+ valid? app_exist == true, "The path you specified isn't a valid Rails application."
58
+
59
+ valid_dir? File.dirname(@log_file), "Path to log file not valid: #@log_file"
60
+ valid_dir? File.dirname(@pid_file), "Path to pid file not valid: #@pid_file"
61
+ valid_dir? @docroot, "Path to docroot not valid: #@docroot"
62
+ valid_exists? @mime_map, "MIME mapping file does not exist: #@mime_map" if @mime_map
63
+ valid_exists? @config_file, "Config file not there: #@config_file" if @config_file
64
+
65
+ # We should validate service existance here, right Zed?
66
+ begin
67
+ valid? !Win32::Service.exists?(@svc_name), "The service already exist, please remove it first."
68
+ rescue
69
+ end
70
+
71
+ valid? @svc_name != nil, "A service name is mandatory."
72
+
73
+ # default service display to service name
74
+ @svc_display = @svc_name if !@svc_display
75
+
76
+ return @valid
77
+ end
78
+
79
+ def run
80
+ gem 'win32-service', '>= 0.5.2', '< 0.6.0'
81
+ require 'win32/service'
82
+
83
+ # check if mongrel_service.exe is in ruby bindir.
84
+ gem_root = File.join(File.dirname(__FILE__), "..", "..")
85
+ gem_executable = File.join(gem_root, "bin/mongrel_service.exe")
86
+ bindir_executable = File.join(Config::CONFIG['bindir'], '/mongrel_service.exe')
87
+
88
+ unless File.exist?(bindir_executable)
89
+ STDERR.puts "** Copying native mongrel_service executable..."
90
+ FileUtils.cp gem_executable, bindir_executable rescue nil
91
+ end
92
+
93
+ unless FileUtils.compare_file(bindir_executable, gem_executable)
94
+ STDERR.puts "** Updating native mongrel_service executable..."
95
+ FileUtils.rm_f bindir_executable rescue nil
96
+ FileUtils.cp gem_executable, bindir_executable rescue nil
97
+ end
98
+
99
+ # build the command line
100
+ argv = []
101
+
102
+ # start using the native executable
103
+ argv << '"' + bindir_executable + '"'
104
+
105
+ # use the 'single' service for now
106
+ argv << "single"
107
+
108
+ # command line setting override config file settings
109
+ @options = { :host => @address, :port => @port, :cwd => @cwd,
110
+ :log_file => @log_file, :pid_file => @pid_file, :environment => @environment,
111
+ :docroot => @docroot, :mime_map => @mime_map,
112
+ :debug => @debug, :includes => ["mongrel"], :config_script => @config_script,
113
+ :num_procs => @num_procs, :timeout => @timeout, :cpu => @cpu, :prefix => @prefix
114
+ }
115
+
116
+ # if we are using a config file, pass -c and -C to the service instead of each start parameter.
117
+ if @config_file
118
+ STDERR.puts "** Using #{@config_file} instead of command line parameters."
119
+ conf = YAML.load_file(@config_file)
120
+
121
+ # add the root folder (-c)
122
+ argv << "-c \"#{conf[:cwd]}\""
123
+
124
+ # use the config file
125
+ argv << "-C \"#{@config_file}\""
126
+
127
+ else
128
+ # use the command line instead
129
+ # now the options
130
+ argv << "-e #{@options[:environment]}" if @options[:environment]
131
+ argv << "-p #{@options[:port]}"
132
+ argv << "-a #{@options[:host]}" if @options[:host]
133
+ argv << "-l \"#{@options[:log_file]}\"" if @options[:log_file]
134
+ argv << "-P \"#{@options[:pid_file]}\""
135
+ argv << "-c \"#{@options[:cwd]}\"" if @options[:cwd]
136
+ argv << "-t #{@options[:timeout]}" if @options[:timeout]
137
+ argv << "-m \"#{@options[:mime_map]}\"" if @options[:mime_map]
138
+ argv << "-r \"#{@options[:docroot]}\"" if @options[:docroot]
139
+ argv << "-n #{@options[:num_procs]}" if @options[:num_procs]
140
+ argv << "-B" if @options[:debug]
141
+ argv << "-S \"#{@options[:config_script]}\"" if @options[:config_script]
142
+ argv << "-u #{@options[:cpu.to_i]}" if @options[:cpu]
143
+ argv << "--prefix \"#{@options[:prefix]}\"" if @options[:prefix]
144
+ end
145
+
146
+ svc = Win32::Service.new
147
+ begin
148
+ svc.create_service{ |s|
149
+ s.service_name = @svc_name
150
+ s.display_name = @svc_display
151
+ s.binary_path_name = argv.join ' '
152
+ s.dependencies = []
153
+ s.service_type = Win32::Service::WIN32_OWN_PROCESS
154
+ }
155
+ puts "Mongrel service '#{@svc_display}' installed as '#{@svc_name}'."
156
+ rescue Win32::ServiceError => err
157
+ puts "There was a problem installing the service:"
158
+ puts err
159
+ end
160
+ svc.close
161
+ end
162
+ end
163
+
164
+ module ServiceValidation
165
+ def configure
166
+ options [
167
+ ['-N', '--name SVC_NAME', "Required name for the service to be registered/installed.", :@svc_name, nil],
168
+ ]
169
+ end
170
+
171
+ def validate
172
+ valid? @svc_name != nil, "A service name is mandatory."
173
+
174
+ gem 'win32-service', '>= 0.5.2', '< 0.6.0'
175
+ require 'win32/service'
176
+
177
+ # Validate that the service exists
178
+ begin
179
+ valid? Win32::Service.exists?(@svc_name), "There is no service with that name, cannot proceed."
180
+ Win32::Service.open(@svc_name) do |svc|
181
+ valid? svc.binary_path_name.include?("mongrel_service"), "The service specified isn't a Mongrel service."
182
+ end
183
+ rescue
184
+ end
185
+
186
+ return @valid
187
+ end
188
+ end
189
+
190
+ class Remove < GemPlugin::Plugin "/commands"
191
+ include Mongrel::Command::Base
192
+ include ServiceValidation
193
+
194
+ def run
195
+ gem 'win32-service', '>= 0.5.2', '< 0.6.0'
196
+ require 'win32/service'
197
+
198
+ display_name = Win32::Service.getdisplayname(@svc_name)
199
+
200
+ begin
201
+ Win32::Service.stop(@svc_name)
202
+ rescue
203
+ end
204
+ begin
205
+ Win32::Service.delete(@svc_name)
206
+ rescue
207
+ end
208
+ puts "#{display_name} service removed."
209
+ end
210
+ end
211
+ end
@@ -0,0 +1,117 @@
1
+
2
+ # Gem::Specification for Mongrel_service-0.3.4
3
+ # Originally generated by Echoe
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = %q{mongrel_service}
7
+ s.version = "0.3.4"
8
+ s.date = %q{2008-01-02}
9
+ s.summary = %q{Mongrel Native Win32 Service Plugin for Rails}
10
+ s.email = %q{}
11
+ s.homepage = %q{http://rubyforge.org/projects/mongrel}
12
+ s.rubyforge_project = %q{mongrel}
13
+ s.description = %q{This plugin offer native win32 services for rails, powered by Mongrel.}
14
+ s.has_rdoc = true
15
+ s.platform = %q{x86-mingw32}
16
+ s.authors = ["Luis Lavena"]
17
+ s.files = ["bin/mongrel_service.exe", "tools/freebasic.rb", "TODO", "resources/defaults.yaml", "README", "native/mongrel_service.bi", "native/mongrel_service.bas", "native/console_process.bi", "native/console_process.bas", "native/_debug.bi", "LICENSE", "lib/ServiceFB/ServiceFB_Utils.bi", "lib/ServiceFB/ServiceFB_Utils.bas", "lib/ServiceFB/ServiceFB.bi", "lib/ServiceFB/ServiceFB.bas", "lib/ServiceFB/_utils_internals.bi", "lib/ServiceFB/_internals.bi", "lib/mongrel_service/init.rb", "COPYING", "CHANGELOG", "Manifest", "mongrel_service.gemspec"]
18
+ s.add_dependency(%q<gem_plugin>, [">= 0.2.3", "< 0.3.0"])
19
+ s.add_dependency(%q<mongrel>, [">= 1.0.2", "< 1.2.0"])
20
+ s.add_dependency(%q<win32-service>, [">= 0.5.2", "< 0.6.0"])
21
+ end
22
+
23
+
24
+ # # Original Rakefile source (requires the Echoe gem):
25
+ #
26
+ # require 'echoe'
27
+ # require 'tools/freebasic'
28
+ #
29
+ # # Task :package needs compile before doing the gem stuff.
30
+ # # (weird behavior of Rake?)
31
+ # task :package => [:compile]
32
+ #
33
+ # echoe_spec = Echoe.new("mongrel_service") do |p|
34
+ # p.summary = "Mongrel Native Win32 Service Plugin for Rails"
35
+ # p.summary += " (debug build)" unless ENV['RELEASE']
36
+ # p.description = "This plugin offer native win32 services for rails, powered by Mongrel."
37
+ # p.author = "Luis Lavena"
38
+ # p.platform = Gem::Platform::CURRENT
39
+ # p.dependencies = [['gem_plugin', '>=0.2.3', '<0.3.0'],
40
+ # ['mongrel', '>=1.0.2', '<1.2.0'],
41
+ # ['win32-service', '>=0.5.2', '<0.6.0']]
42
+ #
43
+ # p.executable_pattern = ""
44
+ #
45
+ # p.need_tar_gz = false
46
+ # p.need_zip = true
47
+ # ]
48
+ # p.require_signed = true
49
+ # end
50
+ #
51
+ # desc "Compile native code"
52
+ # task :compile => [:native_lib, :native_service]
53
+ #
54
+ # # global options shared by all the project in this Rakefile
55
+ # OPTIONS = {
56
+ # :debug => false,
57
+ # :profile => false,
58
+ # :errorchecking => :ex,
59
+ # :mt => true,
60
+ # :pedantic => true }
61
+ #
62
+ # OPTIONS[:debug] = true if ENV['DEBUG']
63
+ # OPTIONS[:profile] = true if ENV['PROFILE']
64
+ # OPTIONS[:errorchecking] = :exx if ENV['EXX']
65
+ # OPTIONS[:pedantic] = false if ENV['NOPEDANTIC']
66
+ #
67
+ # # ServiceFB namespace (lib)
68
+ # namespace :lib do
69
+ # project_task 'servicefb' do
70
+ # lib 'ServiceFB'
71
+ # build_to 'lib'
72
+ #
73
+ # define 'SERVICEFB_DEBUG_LOG' unless ENV['RELEASE']
74
+ # source 'lib/ServiceFB/ServiceFB.bas'
75
+ #
76
+ # option OPTIONS
77
+ # end
78
+ #
79
+ # project_task 'servicefb_utils' do
80
+ # lib 'ServiceFB_Utils'
81
+ # build_to 'lib'
82
+ #
83
+ # define 'SERVICEFB_DEBUG_LOG' unless ENV['RELEASE']
84
+ # source 'lib/ServiceFB/ServiceFB_Utils.bas'
85
+ #
86
+ # option OPTIONS
87
+ # end
88
+ # end
89
+ #
90
+ # # add lib namespace to global tasks
91
+ # #include_projects_of :lib
92
+ # task :native_lib => "lib:build"
93
+ # task :clean => "lib:clobber"
94
+ #
95
+ # # mongrel_service (native)
96
+ # namespace :native do
97
+ # project_task 'mongrel_service' do
98
+ # executable 'mongrel_service'
99
+ # build_to 'bin'
100
+ #
101
+ # define 'DEBUG_LOG' unless ENV['RELEASE']
102
+ # define "GEM_VERSION=#{echoe_spec.version}"
103
+ #
104
+ # main 'native/mongrel_service.bas'
105
+ # source 'native/console_process.bas'
106
+ #
107
+ # lib_path 'lib'
108
+ # library 'ServiceFB', 'ServiceFB_Utils'
109
+ # library 'user32', 'advapi32', 'psapi'
110
+ #
111
+ # option OPTIONS
112
+ # end
113
+ # end
114
+ #
115
+ # #include_projects_of :native
116
+ # task :native_service => "native:build"
117
+ # task :clean => "native:clobber"