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,179 @@
1
+ '##################################################################
2
+ '#
3
+ '# mongrel_service: Win32 native implementation for mongrel
4
+ '# (using ServiceFB and FreeBASIC)
5
+ '#
6
+ '# Copyright (c) 2006 Multimedia systems
7
+ '# (c) and code by Luis Lavena
8
+ '#
9
+ '# mongrel_service (native) and mongrel_service gem_pluing are licensed
10
+ '# in the same terms as mongrel, please review the mongrel license at
11
+ '# http://mongrel.rubyforge.org/license.html
12
+ '#
13
+ '##################################################################
14
+
15
+ '##################################################################
16
+ '# Requirements:
17
+ '# - FreeBASIC 0.18
18
+ '#
19
+ '##################################################################
20
+
21
+ #include once "mongrel_service.bi"
22
+ #define DEBUG_LOG_FILE EXEPATH + "\mongrel_service.log"
23
+ #include once "_debug.bi"
24
+
25
+ namespace mongrel_service
26
+ constructor SingleMongrel()
27
+ dim redirect_file as string
28
+
29
+ with this.__service
30
+ .name = "single"
31
+ .description = "Mongrel Single Process service"
32
+
33
+ '# disabling shared process
34
+ .shared_process = FALSE
35
+
36
+ '# TODO: fix inheritance here
37
+ .onInit = @single_onInit
38
+ .onStart = @single_onStart
39
+ .onStop = @single_onStop
40
+ end with
41
+
42
+ with this.__console
43
+ redirect_file = EXEPATH + "\mongrel.log"
44
+ debug("redirecting to: " + redirect_file)
45
+ .redirect(ProcessStdBoth, redirect_file)
46
+ end with
47
+
48
+ '# TODO: fix inheritance here
49
+ single_mongrel_ref = @this
50
+ end constructor
51
+
52
+ destructor SingleMongrel()
53
+ '# TODO: fin inheritance here
54
+ end destructor
55
+
56
+ function single_onInit(byref self as ServiceProcess) as integer
57
+ dim result as integer
58
+ dim mongrel_cmd as string
59
+
60
+ debug("single_onInit()")
61
+
62
+ '# ruby.exe must be in the path, which we guess is already there.
63
+ '# because mongrel_service executable (.exe) is located in the same
64
+ '# folder than mongrel_rails ruby script, we complete the path with
65
+ '# EXEPATH + "\mongrel_rails" to make it work.
66
+ '# FIXED ruby installation outside PATH and inside folders with spaces
67
+ mongrel_cmd = !"\"" + EXEPATH + !"\\ruby.exe" + !"\" " + !"\"" + EXEPATH + !"\\mongrel_rails" + !"\"" + " start"
68
+
69
+ '# due lack of inheritance, we use single_mongrel_ref as pointer to
70
+ '# SingleMongrel instance. now we should call StillAlive
71
+ self.StillAlive()
72
+ if (len(self.commandline) > 0) then
73
+ '# assign the program
74
+ single_mongrel_ref->__console.filename = mongrel_cmd
75
+ single_mongrel_ref->__console.arguments = self.commandline
76
+
77
+ '# fix commandline, it currently contains params to be passed to
78
+ '# mongrel_rails, and not ruby.exe nor the script to be run.
79
+ self.commandline = mongrel_cmd + " " + self.commandline
80
+
81
+ '# now launch the child process
82
+ debug("starting child process with cmdline: " + self.commandline)
83
+ single_mongrel_ref->__child_pid = 0
84
+ if (single_mongrel_ref->__console.start() = true) then
85
+ single_mongrel_ref->__child_pid = single_mongrel_ref->__console.pid
86
+ end if
87
+ self.StillAlive()
88
+
89
+ '# check if pid is valid
90
+ if (single_mongrel_ref->__child_pid > 0) then
91
+ '# it worked
92
+ debug("child process pid: " + str(single_mongrel_ref->__child_pid))
93
+ result = not FALSE
94
+ end if
95
+ else
96
+ '# if no param, no service!
97
+ debug("no parameters was passed to this service!")
98
+ result = FALSE
99
+ end if
100
+
101
+ debug("single_onInit() done")
102
+ return result
103
+ end function
104
+
105
+ sub single_onStart(byref self as ServiceProcess)
106
+ debug("single_onStart()")
107
+
108
+ do while (self.state = Running) or (self.state = Paused)
109
+ '# instead of sitting idle here, we must monitor the pid
110
+ '# and re-spawn a new process if needed
111
+ if not (single_mongrel_ref->__console.running = true) then
112
+ '# check if we aren't terminating
113
+ if (self.state = Running) or (self.state = Paused) then
114
+ debug("child process terminated!, re-spawning a new one")
115
+
116
+ single_mongrel_ref->__child_pid = 0
117
+ if (single_mongrel_ref->__console.start() = true) then
118
+ single_mongrel_ref->__child_pid = single_mongrel_ref->__console.pid
119
+ end if
120
+
121
+ if (single_mongrel_ref->__child_pid > 0) then
122
+ debug("new child process pid: " + str(single_mongrel_ref->__child_pid))
123
+ end if
124
+ end if
125
+ end if
126
+
127
+ '# wait for 5 seconds
128
+ sleep 5000
129
+ loop
130
+
131
+ debug("single_onStart() done")
132
+ end sub
133
+
134
+ sub single_onStop(byref self as ServiceProcess)
135
+ debug("single_onStop()")
136
+
137
+ '# now terminates the child process
138
+ if not (single_mongrel_ref->__child_pid = 0) then
139
+ debug("trying to kill pid: " + str(single_mongrel_ref->__child_pid))
140
+ if not (single_mongrel_ref->__console.terminate() = true) then
141
+ debug("Terminate() reported a problem when terminating process " + str(single_mongrel_ref->__child_pid))
142
+ else
143
+ debug("child process terminated with success.")
144
+ single_mongrel_ref->__child_pid = 0
145
+ end if
146
+ end if
147
+
148
+ debug("single_onStop() done")
149
+ end sub
150
+
151
+ sub application()
152
+ dim simple as SingleMongrel
153
+ dim host as ServiceHost
154
+ dim ctrl as ServiceController = ServiceController("Mongrel Win32 Service", "version " + VERSION, _
155
+ "(c) 2006 The Mongrel development team.")
156
+
157
+ '# add SingleMongrel (service)
158
+ host.Add(simple.__service)
159
+ select case ctrl.RunMode()
160
+ '# call from Service Control Manager (SCM)
161
+ case RunAsService:
162
+ debug("ServiceHost RunAsService")
163
+ host.Run()
164
+
165
+ '# call from console, useful for debug purposes.
166
+ case RunAsConsole:
167
+ debug("ServiceController Console")
168
+ ctrl.Console()
169
+
170
+ case else:
171
+ ctrl.Banner()
172
+ print "mongrel_service is not designed to run form commandline,"
173
+ print "please use mongrel_rails service:: commands to create a win32 service."
174
+ end select
175
+ end sub
176
+ end namespace
177
+
178
+ '# MAIN: start native mongrel_service here
179
+ mongrel_service.application()
@@ -0,0 +1,61 @@
1
+ '##################################################################
2
+ '#
3
+ '# mongrel_service: Win32 native implementation for mongrel
4
+ '# (using ServiceFB and FreeBASIC)
5
+ '#
6
+ '# Copyright (c) 2006 Multimedia systems
7
+ '# (c) and code by Luis Lavena
8
+ '#
9
+ '# mongrel_service (native) and mongrel_service gem_pluing are licensed
10
+ '# in the same terms as mongrel, please review the mongrel license at
11
+ '# http://mongrel.rubyforge.org/license.html
12
+ '#
13
+ '##################################################################
14
+
15
+ '##################################################################
16
+ '# Requirements:
17
+ '# - FreeBASIC 0.18.
18
+ '#
19
+ '##################################################################
20
+
21
+ #define SERVICEFB_INCLUDE_UTILS
22
+ #include once "lib/ServiceFB/ServiceFB.bi"
23
+ #include once "console_process.bi"
24
+
25
+ '# use for debug versions
26
+ #if not defined(GEM_VERSION)
27
+ #define GEM_VERSION (debug mode)
28
+ #endif
29
+
30
+ '# preprocessor stringize
31
+ #define PPSTR(x) #x
32
+
33
+ namespace mongrel_service
34
+ const VERSION as string = PPSTR(GEM_VERSION)
35
+
36
+ '# namespace include
37
+ using fb.svc
38
+ using fb.svc.utils
39
+
40
+ declare function single_onInit(byref as ServiceProcess) as integer
41
+ declare sub single_onStart(byref as ServiceProcess)
42
+ declare sub single_onStop(byref as ServiceProcess)
43
+
44
+ '# SingleMongrel
45
+ type SingleMongrel
46
+ declare constructor()
47
+ declare destructor()
48
+
49
+ '# TODO: replace for inheritance here
50
+ 'declare function onInit() as integer
51
+ 'declare sub onStart()
52
+ 'declare sub onStop()
53
+
54
+ __service as ServiceProcess
55
+ __console as ConsoleProcess
56
+ __child_pid as uinteger
57
+ end type
58
+
59
+ '# TODO: replace with inheritance here
60
+ dim shared single_mongrel_ref as SingleMongrel ptr
61
+ end namespace
@@ -0,0 +1,2 @@
1
+ ---
2
+ :debug: false
@@ -0,0 +1,355 @@
1
+ #--
2
+ # FreeBASIC project builder
3
+ # inspired by Asset Compiler by Jeremy Voorhis
4
+ # coded by Luis Lavena
5
+ #--
6
+
7
+ # FreeBASIC Project library for compilation.
8
+ # For example:
9
+ #
10
+ # namespace :projects do
11
+ # project_task :my_fb_project do
12
+ # lib 'static'
13
+ # dylib 'dynamic library'
14
+ # executable 'exename'
15
+ #
16
+ # build_to 'bin'
17
+ #
18
+ # define 'MY_DEFINE'
19
+ #
20
+ # main 'src/main.bas'
21
+ # source 'src/other_module.bas'
22
+ # source "src/*.bas"
23
+ # end
24
+ # end
25
+ #
26
+ # This example defines the following tasks:
27
+ #
28
+ # rake projects:build # Build all projects
29
+ # rake projects:clobber # Clobber all projects
30
+ # rake projects:my_fb_project:build # Build the my_fb_project files
31
+ # rake projects:my_fb_project:clobber # Remove the my_fb_project files
32
+ # rake projects:my_fb_project:rebuild # Force a rebuild of the my_fb_project files
33
+ # rake projects:rebuild # Rebuild all projects
34
+
35
+ require 'rake/tasklib'
36
+ require 'pp'
37
+
38
+ module FreeBASIC
39
+ # this help me reduce the attempts to remove already removed files.
40
+ # works with src_files
41
+ CLOBBER = Rake::FileList.new
42
+ ON_WINDOWS = (RUBY_PLATFORM =~ /mswin|cygwin|bccwin/)
43
+
44
+ class ProjectTask
45
+ attr_accessor :name
46
+ attr_accessor :output_name
47
+ attr_accessor :type
48
+ attr_accessor :build_path
49
+ attr_accessor :defines
50
+ attr_accessor :main_file
51
+ attr_accessor :sources
52
+ attr_accessor :libraries
53
+ attr_accessor :search_path
54
+ attr_accessor :libraries_path
55
+
56
+ def initialize(name, &block)
57
+ @name = name.to_s
58
+ @build_path = '.'
59
+ @defines = []
60
+ @sources = Rake::FileList.new
61
+ @libraries = []
62
+ @search_path = []
63
+ @libraries_path = []
64
+ @options = {}
65
+
66
+ instance_eval &block
67
+
68
+ do_cleanup
69
+
70
+ namespace @name do
71
+ define_clobber_task
72
+ define_rebuild_task
73
+ define_build_directory_task
74
+ define_build_task
75
+ end
76
+ add_dependencies_to_main_task
77
+ end
78
+
79
+ public
80
+ # using this will set your project type to :executable
81
+ # and assign exe_name as the output_name for the project
82
+ # it dynamically will assign extension when running on windows
83
+ def executable(exe_name)
84
+ @type = :executable
85
+ @output_name = "#{exe_name}.#{(ON_WINDOWS ? "exe" : "")}"
86
+ @real_file_name = @output_name
87
+ end
88
+
89
+ # lib will set type to :lib and assign 'lib#{lib_name}.a'
90
+ # as output_name for the project
91
+ def lib(lib_name)
92
+ @type = :lib
93
+ @output_name = lib_name
94
+ @real_file_name = "lib#{lib_name}.a"
95
+ end
96
+
97
+ # dynlib will set type to :dynlib and assign '#{dll_name}.dll|so'
98
+ # as output_name for this project
99
+ def dylib(dll_name)
100
+ @type = :dylib
101
+ @output_name = "#{dll_name}.#{(ON_WINDOWS ? "dll" : "so")}"
102
+ @real_file_name = @output_name
103
+ @complement_file = "lib#{@output_name}.a"
104
+ end
105
+
106
+ # this set where the final, compiled executable should be linked
107
+ # uses @build_path as variable
108
+ def build_to(path)
109
+ @build_path = path
110
+ end
111
+
112
+ # define allow you set compiler time options
113
+ # collect them into @defines and use later
114
+ # to call source file compilation process (it wil require cleanup)
115
+ def define(*defines)
116
+ @defines << defines
117
+ end
118
+
119
+ # main set @main_file to be the main module used during the linking
120
+ # process. also, this module requires special -m flag during his
121
+ # own compile process
122
+ # question: in case @no main_file was set, will use the first 'source'
123
+ # file defined as main? or it should raise a error?
124
+ def main(main_file)
125
+ @main_file = main_file
126
+ end
127
+
128
+ # used to collect sources files for compilation
129
+ # it will take .bas, .rc, .res as sources
130
+ # before compilation we should clean @sources!
131
+ def source(*sources)
132
+ @sources.include sources
133
+ end
134
+
135
+ # this is similar to sources, instead library linking is used
136
+ # also will require cleanup services ;-)
137
+ def library(*libraries)
138
+ @libraries << libraries
139
+ end
140
+
141
+ # use this to set the include path when looking for, ehem, includes
142
+ # (equals -i fbc compiler param)
143
+ def search_path(*search_path)
144
+ @search_path << search_path
145
+ end
146
+
147
+ # use this to tell the compiler where to look for libraries
148
+ # (equals -p fbc compiler param)
149
+ def lib_path(*libraries_path)
150
+ @libraries_path << libraries_path
151
+ end
152
+
153
+ # use this to add additional compiler parameters (like debug or errorchecking options)
154
+ #
155
+ def option(new_options = {})
156
+ @options.merge!(new_options)
157
+ end
158
+
159
+ protected
160
+ # this method will fix nested libraries and defines
161
+ # also, if main_file is missing (or wasn't set) will shift the first one
162
+ # as main
163
+ def do_cleanup
164
+ # remove duplicated definitions, flatten
165
+ @defines.flatten!
166
+ @defines.uniq! if @defines.length > 1
167
+
168
+ # set main_file
169
+ if @type == :executable
170
+ @main_file = @sources.shift unless defined?(@main_file)
171
+ end
172
+
173
+ # empty path? must be corrected
174
+ @build_path = '.' if @build_path == ''
175
+
176
+ # remove duplicates from sources
177
+ @sources.uniq! if @sources.length > 1
178
+
179
+ # now the libraries
180
+ @libraries.flatten!
181
+ @libraries.uniq! if @libraries.length > 1
182
+
183
+ # search path
184
+ @search_path.flatten!
185
+ @search_path.uniq! if @search_path.length > 1
186
+
187
+ # libraries path
188
+ @libraries_path.flatten!
189
+ @libraries_path.uniq! if @libraries_path.length > 1
190
+
191
+ # if no target was set, default to executable
192
+ unless defined?(@output_name)
193
+ executable(@name)
194
+ end
195
+ end
196
+
197
+ # return the compiled name version of the passed source file (src)
198
+ # compiled_form("test.bas") => "test.o"
199
+ def compiled_form(src)
200
+ src.ext({ ".bas" => "o", ".rc" => "obj" }[File.extname(src)])
201
+ end
202
+
203
+ def compiled_project_file
204
+ File.join @build_path, @real_file_name
205
+ end
206
+
207
+ def fbc_compile(source, target, main = nil)
208
+ cmdline = []
209
+ cmdline << "fbc"
210
+ cmdline << "-g" if (@options.has_key?(:debug) && @options[:debug] == true)
211
+ cmdline << "-#{@options[:errorchecking].to_s}" if @options.has_key?(:errorchecking)
212
+ cmdline << "-profile" if (@options.has_key?(:profile) && @options[:profile] == true)
213
+ cmdline << "-mt" if (@options.has_key?(:mt) && @options[:mt] == true)
214
+ cmdline << "-w pedantic" if (@options.has_key?(:pedantic) && @options[:pedantic] == true)
215
+ cmdline << "-c #{source}"
216
+ cmdline << "-o #{target}"
217
+ cmdline << "-m #{main}" unless main.nil?
218
+ cmdline << @defines.collect { |defname| "-d #{defname}" }
219
+ cmdline << @search_path.collect { |path| "-i #{path}" }
220
+ cmdline.flatten.join(' ')
221
+ end
222
+
223
+ def fbc_link(target, files, extra_files = [])
224
+ cmdline = []
225
+ cmdline << "fbc"
226
+ cmdline << "-g" if (@options.has_key?(:debug) && @options[:debug] == true)
227
+ cmdline << "-profile" if (@options.has_key?(:profile) && @options[:profile] == true)
228
+ cmdline << "-mt" if (@options.has_key?(:mt) && @options[:mt] == true)
229
+ cmdline << "-#{@type.to_s}" unless @type == :executable
230
+ cmdline << "-x #{target}"
231
+ cmdline << files << extra_files
232
+ cmdline << @defines.collect { |defname| "-d #{defname}" }
233
+ unless @type == :lib
234
+ cmdline << @libraries_path.collect { |path| "-p #{path}" }
235
+ cmdline << @libraries.collect { |libname| "-l #{libname}" }
236
+ end
237
+ cmdline.flatten.join(' ')
238
+ end
239
+
240
+ def define_clobber_task
241
+ desc "Remove all compiled files for #{@name}"
242
+ task :clobber do
243
+ # remove compiled and linked file
244
+ rm compiled_project_file rescue nil #unless @type == :lib
245
+ rm File.join(@build_path, @complement_file) rescue nil if @type == :dylib
246
+
247
+ # remove main file
248
+ rm compiled_form(@main_file) rescue nil
249
+
250
+ # now the sources files
251
+ # avoid attempt to remove the file two times (this is a bug in Rake)
252
+ @sources.each do |src|
253
+ # exclude compiled source files (c obj).
254
+ unless src =~ /o$/
255
+ target = compiled_form(src)
256
+ unless CLOBBER.include?(target)
257
+ CLOBBER.include(target)
258
+ rm target rescue nil
259
+ end
260
+ end
261
+ end
262
+ end
263
+ end
264
+
265
+ def define_rebuild_task
266
+ desc "Force a rebuild of files for #{@name}"
267
+ task :rebuild => [:clobber, :build]
268
+ end
269
+
270
+ def define_build_directory_task
271
+ directory @build_path
272
+ task :build => @build_path
273
+ end
274
+
275
+ def define_build_task
276
+ desc "Build project #{@name}"
277
+ task :build
278
+
279
+ # empty file task
280
+ file compiled_project_file
281
+
282
+ # compile main_file
283
+ # use as pre-requisite the source filename
284
+ if @type == :executable
285
+ file compiled_form(@main_file) => @main_file do |t|
286
+ # remove the path and the extension
287
+ main_module = File.basename(t.name).ext
288
+ sh fbc_compile(@main_file, t.name, main_module)
289
+ end
290
+
291
+ # add dependency
292
+ file compiled_project_file => compiled_form(@main_file)
293
+ end
294
+
295
+ # gather files that are passed "as-is" to the compiler
296
+ unprocessed_files = @sources.select { |rcfile| rcfile =~ /(res|rc|o|obj)$/ }
297
+
298
+ @sources.each do |src|
299
+ # is a unprocessed file?
300
+ unless unprocessed_files.include?(src)
301
+ target = compiled_form(src)
302
+
303
+ # is already in our list of tasks?
304
+ if not Rake::Task.task_defined?(target)
305
+ # if not, compile
306
+
307
+ file target => src do
308
+ sh fbc_compile(src, target)
309
+ end
310
+ end
311
+
312
+ # include dependency
313
+ file compiled_project_file => target
314
+ end
315
+ end
316
+
317
+ # now the linking process
318
+ file compiled_project_file do |t|
319
+ target = File.join(@build_path, @output_name)
320
+ sh fbc_link(target, t.prerequisites, unprocessed_files)
321
+ end
322
+
323
+ # add the dependency
324
+ task :build => compiled_project_file
325
+ end
326
+
327
+ # Adds dependencies in the parent namespace
328
+ def add_dependencies_to_main_task
329
+ desc 'Build all projects' unless task( :build ).comment
330
+ task :build => "#{@name}:build"
331
+
332
+ desc 'Clobber all projects' unless task( :clobber ).comment
333
+ task :clobber => "#{@name}:clobber"
334
+
335
+ desc 'Rebuild all projects' unless task( :rebuild ).comment
336
+ task :rebuild => ["#{@name}:clobber", "#{@name}:build"]
337
+ end
338
+ end
339
+ end
340
+
341
+ # helper method to define a FreeBASIC::ProjectTask in the current namespace
342
+ def project_task name, &block
343
+ FreeBASIC::ProjectTask.new name, &block
344
+ end
345
+
346
+ def include_projects_of name
347
+ desc 'Build all projects' unless task( :build ).comment
348
+ task :build => "#{name}:build"
349
+
350
+ desc 'Clobber all projects' unless task( :clobber ).comment
351
+ task :clobber => "#{name}:clobber"
352
+
353
+ desc 'Rebuild all projects' unless task( :rebuild ).comment
354
+ task :rebuild => "#{name}:rebuild"
355
+ end