daemon-ogre 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,569 @@
1
+ #DaemonOgreBody
2
+ begin
3
+ module DaemonOgre
4
+
5
+ #config
6
+ begin
7
+ class App
8
+ class << self
9
+ attr_accessor :log_path,
10
+ :pid_path,
11
+ :app_name,
12
+ :port,
13
+ :terminate,
14
+ :debug
15
+ end
16
+ end
17
+ end
18
+
19
+ #default
20
+ App.log_path = "./var/log/logfile.log"
21
+ App.pid_path = "./var/pid/pidfile.pid"
22
+ App.terminate = false
23
+ App.port = 80
24
+ App.app_name = $0
25
+ App.debug = false
26
+
27
+ #OgreClassMethods
28
+ begin
29
+ class << self
30
+ #Based on the rb location
31
+ def load_directory(directory,*args)
32
+ arg = Hash[*args]
33
+
34
+ if !arg[:delayed].nil?
35
+ raise ArgumentError, "Delayed items must be in an "+\
36
+ "Array! Example:\n:delayed => ['abc']" if arg[:delayed].class == Array
37
+ end
38
+
39
+ if !arg[:exclude].nil?
40
+ raise ArgumentError, "Exclude items must be in an "+\
41
+ "Array! Example:\n:exclude => ['abc']" if arg[:exclude].class == Array
42
+ end
43
+
44
+
45
+ #=================================================================================================================
46
+
47
+ puts "LOADING_FILES_FROM_"+directory.to_s.split('/').last.split('.').first.capitalize if App.debug
48
+
49
+ delayed_loads = Array.new
50
+ Dir["#{directory}/**/*.rb"].each do |file|
51
+
52
+ arg[:delayed]= [nil] if arg[:delayed].nil?
53
+ arg[:exclude]= [nil] if arg[:exclude].nil?
54
+
55
+ arg[:exclude].each do |except|
56
+ if file.split('/').last.split('.').first == except.to_s.split('.').first
57
+ puts file.to_s + " cant be loaded because it's an exception"
58
+ else
59
+ arg[:delayed].each do |delay|
60
+ if file.split('/').last.split('.').first == delay.to_s.split('.').first
61
+ delayed_loads.push(file)
62
+ else
63
+ load(file)
64
+ puts file.to_s
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ delayed_loads.each do |delayed_load_element|
71
+ load(delayed_load_element)
72
+ puts delayed_load_element.to_s if App.debug
73
+ end
74
+ puts "DONE_LOAD_FILES_FROM_"+directory.to_s.split('/').last.split('.').first.capitalize if App.debug
75
+
76
+ end
77
+
78
+ def get_port(port,max_port=65535 ,host="0.0.0.0")
79
+
80
+ require 'socket'
81
+ port = port.to_i
82
+
83
+ begin
84
+ server = TCPServer.new('0.0.0.0', port)
85
+ server.close
86
+ return port
87
+ rescue Errno::EADDRINUSE
88
+ port = port.to_i + 1 if port < max_port+1
89
+ retry
90
+ end
91
+
92
+ end
93
+
94
+ def error_logger(error_msg,prefix="",log_file=App.log_path)
95
+
96
+ create_on_filesystem(log_file)
97
+
98
+ if File.exists?("./#{log_file}")
99
+ error_log = File.open( ".#{log_file}", "a+")
100
+ error_log << "\n#{Time.now} | #{prefix}#{":" if prefix != ""} #{error_msg}"
101
+ error_log.close
102
+ else
103
+ File.new("./#{log_file}", "w").write(
104
+ "#{Time.now} | #{prefix}#{":" if prefix != ""} #{error_msg}"
105
+ )
106
+ end
107
+
108
+ return {:error => error_msg}
109
+ end
110
+
111
+ def load_ymls(directory)
112
+
113
+ require 'yaml'
114
+ #require "hashie"
115
+
116
+ yaml_files = Dir["#{directory}/**/*.yml"].each { |f| puts f.to_s if App.debug }
117
+ puts "\nyaml file found: "+yaml_files.inspect.to_s if App.debug
118
+ @result_hash = {}
119
+ yaml_files.each_with_index do |full_path_file_name|
120
+
121
+
122
+ file_name = full_path_file_name.split('/').last.split('.').first
123
+
124
+ hash_key = file_name
125
+ @result_hash[hash_key] = YAML.load(File.read("#{full_path_file_name}"))
126
+
127
+ #@result_hash = @result_hash.merge!(tmp_hash)
128
+
129
+
130
+ puts "==========================================================" if App.debug
131
+ puts "Loading "+file_name.to_s.capitalize+"\n" if App.debug
132
+ puts YAML.load(File.read("#{full_path_file_name}")) if App.debug
133
+ puts "__________________________________________________________" if App.debug
134
+
135
+ end
136
+
137
+ puts "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" if App.debug
138
+ puts "The Main Hash: \n"+@result_hash.inspect.to_s if App.debug
139
+ puts "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n" if App.debug
140
+
141
+ return @result_hash
142
+ end
143
+
144
+ def create_on_filesystem(input,optionable_data=nil,optionable_file_mod="w")
145
+ begin
146
+
147
+ #file_name generate
148
+ if !input.to_s.split('/').last.nil? || input.to_s.split('/').last != ''
149
+ file_name = input.to_s.split('/').last
150
+ else
151
+ file_name = nil?
152
+ end
153
+
154
+ #path_way
155
+ begin
156
+ raise ArgumentError, "missing input: #{input}" if input.nil?
157
+ path = File.expand_path(input).to_s.split('/')
158
+ path = path - [File.expand_path(input).to_s.split('/').last]
159
+ path.shift
160
+ end
161
+
162
+ #job
163
+ begin
164
+ if !Dir.exists?("/"+path.join("/"))
165
+
166
+ at_now = "/"
167
+ path.each do |dir_to_be_checked|
168
+
169
+ at_now += "#{dir_to_be_checked}/"
170
+ Dir.mkdir(at_now) if !Dir.exists?(at_now)
171
+
172
+ end
173
+ end
174
+ end
175
+
176
+ #file_create
177
+ File.new("/#{path.join("/")}/#{file_name}", optionable_file_mod ).write optionable_data
178
+
179
+ rescue Exception => ex
180
+ puts ex
181
+ end
182
+ end
183
+
184
+ def process_running?(input)
185
+ begin
186
+ Process.getpgid input.chomp.to_i
187
+ return true
188
+ rescue Exception
189
+ return false
190
+ end
191
+ end
192
+
193
+ end
194
+ end
195
+
196
+ #DaemonEngine
197
+ begin
198
+ class Daemon
199
+ # Checks to see if the current process is the child process and if not
200
+ # will update the pid file with the child pid.
201
+ def self.start pid, pidfile, outfile, errfile
202
+ unless pid.nil?
203
+ raise "Fork failed" if pid == -1
204
+ write pid, pidfile #if kill pidfile
205
+ exit
206
+ else
207
+ redirect outfile, errfile
208
+ end
209
+ end
210
+
211
+ # Attempts to write the pid of the forked process to the pid file.
212
+ def self.write pid, pidfile
213
+ DaemonOgre.create_on_filesystem pidfile
214
+ File.open pidfile, "a+" do |new_line|
215
+ new_line.write "#{pid}\n"
216
+ end
217
+ rescue ::Exception => e
218
+ $stderr.puts "While writing the PID to file, unexpected #{e.class}: #{e}"
219
+ Process.kill "HUP", pid
220
+ end
221
+
222
+ # Try and read the existing pid from the pid file and signal the
223
+ # process. Returns true for a non blocking status.
224
+ def self.kill(pidfile)
225
+ opid = open("./#{pidfile}").read.strip.to_i
226
+ Process.kill 'HUP', opid.to_i
227
+ true
228
+ rescue Errno::ENOENT
229
+ $stdout.puts "#{pidfile} did not exist: Errno::ENOENT" if App.debug
230
+ true
231
+ rescue Errno::ESRCH
232
+ $stdout.puts "The process #{opid} did not exist: Errno::ESRCH" if App.debug
233
+ true
234
+ rescue Errno::EPERM
235
+ $stderr.puts "Lack of privileges to manage the process #{opid}: Errno::EPERM" if App.debug
236
+ false
237
+ rescue ::Exception => e
238
+ $stderr.puts "While signaling the PID, unexpected #{e.class}: #{e}" if App.debug
239
+ false
240
+ end
241
+
242
+ # Send stdout and stderr to log files for the child process
243
+ def self.redirect outfile, errfile
244
+ $stdin.reopen '/dev/null'
245
+ out = File.new outfile, "a"
246
+ err = File.new errfile, "a"
247
+ $stdout.reopen out
248
+ $stderr.reopen err
249
+ $stdout.sync = $stderr.sync = true
250
+ end
251
+ end
252
+
253
+ end
254
+
255
+ #server_model
256
+ begin
257
+ class Server
258
+ @@startup = false
259
+ class << self
260
+
261
+ def daemon
262
+ puts "#{$0} daemon watching you..."
263
+ DaemonOgre.create_on_filesystem DaemonOgre::App.pid_path
264
+ DaemonOgre.create_on_filesystem DaemonOgre::App.log_path
265
+ DaemonOgre.create_on_filesystem './var/daemon.stderr.log'
266
+ Daemon.start fork,
267
+ DaemonOgre::App.pid_path,
268
+ DaemonOgre::App.log_path,
269
+ ('./var/daemon.stderr.log')
270
+ end
271
+
272
+ def debug
273
+ App.debug=true
274
+ end
275
+
276
+ def help
277
+ puts "\nyou can use one of these commands: "+\
278
+ "\nstart daemon -d stop restart log -l pid -p port -tcp status reset help"+\
279
+ "\n==============================================================================DESC======>>"
280
+ puts "start\t\t\t\t=> this will start the #{$0}"+\
281
+ "\ndaemon\t\tor -d\t\t=> this will make is daemon process"+\
282
+ "\nstop\t\t\t\t=> this will kill the last process with pidfile"+\
283
+ "\nrestart\t\tor reset\t=> hard restart"+\
284
+ "\nlog\t\tor -l\t\t=> logfile place"+\
285
+ "\npid\t\tor -p\t\t=> pid file place (if you want set the filename as well, put .pid or .txt in the end)"+\
286
+ "\nport\t\tor -tcp\t\t=> user definiated port"+\
287
+ "\nstatus\t\t\t\t=> last process alive?"+\
288
+ "\nhelp\t\t\t\tgive you this msg :)\n"
289
+ DaemonOgre::App.terminate=true
290
+ end
291
+
292
+ def start
293
+ @@startup = true
294
+ end
295
+
296
+ def stop
297
+ puts "#{$0} is going to be FacePalmed..."
298
+ Daemon.kill DaemonOgre::App.pid_path
299
+ kill_with_pid
300
+ File.open(DaemonOgre::App.pid_path, "w").write("")
301
+ terminate
302
+ end
303
+
304
+ def restart
305
+
306
+ Daemon.kill DaemonOgre::App.pid_path
307
+ kill_with_pid
308
+ File.open(DaemonOgre::App.pid_path, "w").write("")
309
+
310
+ start
311
+ end
312
+
313
+ def kill_with_pid
314
+ begin
315
+ if File.exists?(DaemonOgre::App.pid_path)
316
+ puts "PidFile found, processing..." if App.debug
317
+ File.open(DaemonOgre::App.pid_path).each_line do |row|
318
+ begin
319
+ Process.kill 'TERM', row.to_i
320
+ puts "terminated process at: #{row}" if App.debug
321
+ rescue Exception => ex
322
+ puts "At process: #{row}, #{ex}" if App.debug
323
+ end
324
+ end
325
+ else
326
+ system "ps -ef | grep #{$0}"
327
+ #system "netstat --listen"
328
+ #puts "\nLepton is around 10300-10399"
329
+ end
330
+ rescue Exception => ex
331
+ puts "Exception has occured: #{ex}"
332
+ end
333
+ end
334
+
335
+ def terminate
336
+ Process.exit if DaemonOgre::App.terminate
337
+ end
338
+
339
+ def continue?
340
+ Process.exit if !@@startup
341
+ end
342
+
343
+ def set_log(param)
344
+ ARGV.each do |one_parameter|
345
+ if one_parameter == param
346
+ DaemonOgre::App.log_path= ARGV[ARGV.index(one_parameter)+1]
347
+ end
348
+ end
349
+ end
350
+
351
+ def set_pid(param)
352
+ ARGV.each do |one_parameter|
353
+ if one_parameter == param
354
+ if ARGV[ARGV.index(one_parameter)+1].to_s.include?(".pid") ||\
355
+ ARGV[ARGV.index(one_parameter)+1].to_s.include?(".txt")
356
+ DaemonOgre::App.pid_path= ARGV[ARGV.index(one_parameter)+1]
357
+ else
358
+ DaemonOgre::App.pid_path= ARGV[ARGV.index(one_parameter)+1].to_s+"lepton.pid"
359
+ end
360
+ end
361
+ end
362
+ end
363
+
364
+ def set_port(param)
365
+ ARGV.each do |one_parameter|
366
+ if one_parameter == param
367
+ DaemonOgre::App.port= ARGV[ARGV.index(one_parameter)+1]
368
+ end
369
+ end
370
+ end
371
+
372
+ def pid
373
+ begin
374
+ if !DaemonOgre::App.pid_path.nil?
375
+ DaemonOgre::App.pid_path+="lepton.pid" if !DaemonOgre::App.pid_path.include?(".pid")
376
+ pre_path = File.dirname "#{File.dirname(__FILE__)}/#{DaemonOgre::App.pid_path}"
377
+ pre_path_array = pre_path.split('/') - [ pre_path[0].to_s ]
378
+ if !Dir.exists?(pre_path)
379
+ at_now = String.new
380
+ pre_path_array.each do |one_dir_to_be_made|
381
+ #at_now show the place where we are now
382
+ at_now == "" ? at_now += one_dir_to_be_made : at_now += "/"+one_dir_to_be_made
383
+ if !Dir.exists?("#{File.dirname(__FILE__)}/#{at_now}")
384
+ Dir.mkdir("#{File.dirname(__FILE__)}/#{at_now}")
385
+ end
386
+ end
387
+ end
388
+ File.new("#{File.dirname(__FILE__)}/#{DaemonOgre::App.pid_path}", "a+").write Process.pid.to_s+"\n"
389
+ end
390
+ rescue Exception => ex
391
+ error_logger(ex)
392
+ end
393
+ end
394
+
395
+ def pid_check
396
+ if File.exist?(File.expand_path(App.pid_path))
397
+ puts "checking pidfile:"
398
+ text = File.open(File.expand_path(App.pid_path)).read
399
+ text.each_line do |line|
400
+ puts "#{line.chomp}:\t#{DaemonOgre.process_running?(line)}"
401
+ end
402
+ else
403
+ puts "missing pid file (with default path) "+\
404
+ "\nif you specificated one manualy pls type"+\
405
+ " the path first in with '-p xy/xzt.pid'"
406
+ end
407
+ DaemonOgre::App.terminate=true
408
+ end
409
+
410
+ end
411
+ end
412
+ end
413
+
414
+ end
415
+ end
416
+
417
+ #monkey patch
418
+ begin
419
+ class File
420
+ def self.create!(input,optionable_data=nil,optionable_file_mod="w")
421
+ DaemonOgre.create_on_filesystem(input,optionable_data,optionable_file_mod)
422
+ end
423
+ end
424
+ def require_directory(directory,*args)
425
+ DaemonOgre.load_directory(directory,*args)
426
+ end
427
+ def require_ymls(directory)
428
+ DaemonOgre.load_ymls(directory)
429
+ end
430
+ def get_port(port,max_port=65535 ,host="0.0.0.0")
431
+ DaemonOgre.get_port(port,max_port,host)
432
+ end
433
+ def logger(error_msg,prefix="",log_file=DaemonOgre::App.log_path)
434
+ DaemonOgre.error_logger(error_msg,prefix,log_file)
435
+ end
436
+ class Class
437
+ def class_methods
438
+ self.methods - Object.methods
439
+ end
440
+ def self.class_methods
441
+ self.methods - Object.methods
442
+ end
443
+ end
444
+ class Rnd
445
+ class << self
446
+ def string(length,amount=1)
447
+ mrg = String.new
448
+ amount.times do
449
+ a_string = Random.rand(length)
450
+ a_string == 0 ? a_string += 1 : a_string
451
+ mrg_prt = (0...a_string).map{ ('a'..'z').to_a[rand(26)] }.join
452
+ mrg+= " #{mrg_prt}"
453
+ end
454
+ return mrg
455
+ end
456
+
457
+ def number(length)
458
+
459
+ Random.rand(length)
460
+
461
+ end
462
+
463
+ def boolean
464
+
465
+ rand(2) == 1
466
+
467
+ end
468
+
469
+ def date from = Time.at(1114924812), to = Time.now
470
+ rand(from..to)
471
+ end
472
+ end
473
+ end
474
+ class Array
475
+ #class << self
476
+ def index_of(target_element)
477
+ array = self
478
+ hash = Hash[array.map.with_index.to_a]
479
+ return hash[target_element]
480
+ end
481
+ #end
482
+ end
483
+ end
484
+
485
+ #StartUp
486
+ begin
487
+ module DaemonOgre
488
+ def self.start(*args)
489
+ arg = Hash[*args]
490
+
491
+ ##defaults:
492
+ #arg[:log_path]
493
+ #arg[:pid_path]
494
+
495
+ #arg[:name]
496
+ #arg[:port]
497
+
498
+ #arg[:terminate]
499
+
500
+ begin
501
+
502
+ begin
503
+
504
+ App.pid_path = arg[:pid_path] if !arg[:pid_path].nil?
505
+ App.log_path = arg[:log_path] if !arg[:log_path].nil?
506
+
507
+ $0 = arg[:name] if !arg[:name].nil?
508
+ App.port = arg[:port] if !arg[:port].nil?
509
+
510
+ App.terminate = arg[:terminate] if !arg[:terminate].nil?
511
+
512
+ end
513
+
514
+
515
+ if ARGV.nil?
516
+ puts "No server task has been given!"
517
+ DaemonOgre::Server.help
518
+ end
519
+ serv_load = Array.new
520
+ ARGV.each do |one_argv_parameter|
521
+ case one_argv_parameter.downcase
522
+ when "start" then serv_load.push "start"
523
+ when "daemon" then serv_load.push "daemon"
524
+ when "-d" then serv_load.push "daemon"
525
+ when "stop" then serv_load.push "stop"
526
+ when "restart" then serv_load.push "restart"
527
+ when "reset" then serv_load.push "restart"
528
+ when "debugger" then serv_load.push "debugger"
529
+ when "log" then DaemonOgre::Server.set_log "log"
530
+ when "pid" then DaemonOgre::Server.set_pid "pid"
531
+ when "-l" then DaemonOgre::Server.set_log "-l"
532
+ when "-p" then DaemonOgre::Server.set_pid "-p"
533
+ when "port" then DaemonOgre::Server.set_port "port"
534
+ when "-tcp" then DaemonOgre::Server.set_port "-tcp"
535
+ when "status" then DaemonOgre::Server.pid_check
536
+ when "-s" then DaemonOgre::Server.pid_check
537
+ when "help" then DaemonOgre::Server.help
538
+ when "debug" then DaemonOgre::Server.debug
539
+ end
540
+ end
541
+
542
+ #server_TODO
543
+ begin
544
+ DaemonOgre::Server.restart if serv_load.include? "restart"
545
+ DaemonOgre::Server.start if serv_load.include? "start"
546
+ DaemonOgre::Server.stop if serv_load.include? "stop"
547
+ DaemonOgre::Server.daemon if serv_load.include? "daemon"
548
+ end
549
+
550
+ #Continue our program ? : )
551
+ DaemonOgre::Server.continue? if DaemonOgre::App.terminate
552
+
553
+ begin
554
+ require "debugger" ;debugger if serv_load.include? "debugger"
555
+ rescue Exception => ex
556
+ puts "you need to install debugger gem => gem install debugger"
557
+ end
558
+
559
+ end
560
+ end
561
+ #===================-
562
+ def self.help
563
+ puts "\n##defaults:\narg[:log_path]\tlog path and"+\
564
+ " file name\narg[:pid_path]\tpid path and file n"+\
565
+ "ame\narg[:terminate]\tstart command required to"+\
566
+ " continue? 'ruby xy.rb start'\narg[:name]\tapplication names as daemon process"
567
+ end
568
+ end
569
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'daemon-ogre'
16
+
17
+ class Test::Unit::TestCase
18
+ end
@@ -0,0 +1,22 @@
1
+ require_relative "../lib/daemon-ogre.rb"
2
+
3
+ DaemonOgre.start :name => "api_one", #this will be the name of the application
4
+ :log_path => "./var/log/log_file_name", #this will be the logfile place and name
5
+ :pid_path => "./var/pid/pid_file_name", #this will be the pidfile place and name
6
+ :terminate => false #this command not let start your code if it's not started
7
+ # with "start" arguments like :
8
+ # ruby my_awsome_app.rb start
9
+
10
+
11
+
12
+ #my awesome Hello App
13
+ puts "hello App!"
14
+
15
+ i=0
16
+ until i > 1200
17
+ sleep 1
18
+ puts "hello, there! A wonderful day for the #{i}. time! isn't it?"
19
+ i+=1
20
+ end
21
+
22
+ puts "-=end=-"
File without changes