Class: SemiDaemon

Inherits:
Object
  • Object
show all
Defined in:
lib/semi_daemon.rb,
lib/semi_daemon/version.rb

Defined Under Namespace

Modules: Version Classes: SimpleLogFormatter

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSemiDaemon

Returns a new instance of SemiDaemon.



110
111
112
# File 'lib/semi_daemon.rb', line 110

def initialize
  @safe_to_quit=true
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args) ⇒ Object

create instance methods for our class methods



41
42
43
44
45
46
47
# File 'lib/semi_daemon.rb', line 41

def method_missing(m,*args)
  if [:log_file, :pid_file, :interval, :daemon_name,:stop_file].include?(m)
    self.class.send(m) 
  else
    super(m,*args)
  end
end

Class Method Details

.daemon_nameObject



13
14
15
# File 'lib/semi_daemon.rb', line 13

def daemon_name
  self.to_s.underscore
end

.inherited(child) ⇒ Object



29
30
31
32
# File 'lib/semi_daemon.rb', line 29

def inherited(child)
  child.log_file "log/#{child.daemon_name}.log"
  child.pid_file "log/#{child.daemon_name}.pid"
end

.interval(int = nil) ⇒ Object



25
26
27
# File 'lib/semi_daemon.rb', line 25

def interval(int=nil)
  int ? @interval=int : @interval
end

.log_file(log = nil) ⇒ Object



17
18
19
# File 'lib/semi_daemon.rb', line 17

def log_file(log=nil)
  log ? @log_file=log : @log_file
end

.pid_file(pid_file = nil) ⇒ Object



21
22
23
# File 'lib/semi_daemon.rb', line 21

def pid_file(pid_file=nil)
  pid_file ? @pid_file=pid_file : @pid_file
end

.stop_fileObject



34
35
36
# File 'lib/semi_daemon.rb', line 34

def stop_file
  "log/#{daemon_name}.stop"
end

Instance Method Details

#create_pid_fileObject



78
79
80
# File 'lib/semi_daemon.rb', line 78

def create_pid_file
  File.open(pid_file_path,"w") { |f| f.write(Process.pid) }
end

#loggerObject

logging



51
52
53
54
55
56
57
# File 'lib/semi_daemon.rb', line 51

def logger
  @logger ||= begin
    l=Logger.new root(log_file)
    l.formatter = SimpleLogFormatter.new
    l
  end
end

#pid_file_pathObject



74
75
76
# File 'lib/semi_daemon.rb', line 74

def pid_file_path
  root pid_file
end

#root(path) ⇒ Object

process management



61
62
63
64
65
66
67
68
# File 'lib/semi_daemon.rb', line 61

def root(path)
  if defined?(Rails)
    (Rails.root + path).to_s
  else
    dir = File.dirname(__FILE__)
    path[0..0]=="/" ? path : File.join(dir, path)
  end
end

#runObject



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/semi_daemon.rb', line 118

def run
  raise "You must specify `interval 1.minute` or similar in your class to set the interval." if interval.nil?
  return if running?
  Signal.trap("TERM") do 
    @quit=true
    # if it's not safe to quit then we have to trust that our
    # child class will quit when it can or else we'll quit at
    # the beginning of the next event loop
    terminate if @safe_to_quit
  end

  create_pid_file
  logger.info "#{daemon_name} started (PID: #{Process.pid})."
  while(true)
    if wants_quit?
      logger.info "Being asked to stop (#{@quit ? "TERM" : "stop file"}), stopping..."
      terminate
    end
    logger.info "Working..."
    work
    if defined?(ActiveRecord::Base)
      ActiveRecord::Base.clear_active_connections! 
    end
    logger.info "Sleeping for #{interval/60} minutes..."
    # we do this so we can stop more quickly while sleeping
    interval.to_i.times { sleep 1 unless @quit }
  end
end

#running?Boolean

Returns:

  • (Boolean)


82
83
84
85
86
87
# File 'lib/semi_daemon.rb', line 82

def running?
  if File.exists?(pid_file_path)
    pid=File.read(pid_file_path)
    God::System::Process.new(pid).exists?
  end
end

#stop_file_pathObject



70
71
72
# File 'lib/semi_daemon.rb', line 70

def stop_file_path
  root stop_file
end

#terminateObject



93
94
95
96
97
98
99
# File 'lib/semi_daemon.rb', line 93

def terminate
  logger.info "#{daemon_name} stopped."
  Rails.logger.info "#{daemon_name} stopped." if defined?(Rails)
  File.delete(pid_file_path) rescue nil
  File.delete(stop_file_path) rescue nil
  exit
end

#transaction(&block) ⇒ Object



101
102
103
104
105
106
107
108
# File 'lib/semi_daemon.rb', line 101

def transaction(&block)
  terminate if @quit
  @safe_to_quit=false
  r=block.call
  @safe_to_quit=true
  terminate if @quit
  r
end

#wants_quit?Boolean

Returns:

  • (Boolean)


114
115
116
# File 'lib/semi_daemon.rb', line 114

def wants_quit?
  File.exists?(stop_file_path) or @quit
end

#workObject



89
90
91
# File 'lib/semi_daemon.rb', line 89

def work
  raise "You need to define the work method in your subclass of SemiDaemon."
end