daemon-ogre 1.2.0

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,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