Class: Procrastinator::Environment

Inherits:
Object
  • Object
show all
Defined in:
lib/procrastinator/environment.rb

Constant Summary collapse

DEFAULT_LOG_DIRECTORY =
'log/'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(test_mode: false) ⇒ Environment

Returns a new instance of Environment.



7
8
9
10
11
12
13
14
# File 'lib/procrastinator/environment.rb', line 7

def initialize(test_mode: false)
   @test_mode         = test_mode
   @queue_definitions = {}
   @queue_workers     = []
   @processes         = []
   @log_dir           = DEFAULT_LOG_DIRECTORY
   @log_level         = Logger::INFO
end

Instance Attribute Details

#persisterObject (readonly)

Returns the value of attribute persister.



3
4
5
# File 'lib/procrastinator/environment.rb', line 3

def persister
  @persister
end

#processesObject (readonly)

Returns the value of attribute processes.



3
4
5
# File 'lib/procrastinator/environment.rb', line 3

def processes
  @processes
end

#queue_definitionsObject (readonly)

Returns the value of attribute queue_definitions.



3
4
5
# File 'lib/procrastinator/environment.rb', line 3

def queue_definitions
  @queue_definitions
end

#queue_workersObject (readonly)

Returns the value of attribute queue_workers.



3
4
5
# File 'lib/procrastinator/environment.rb', line 3

def queue_workers
  @queue_workers
end

#test_modeObject (readonly)

Returns the value of attribute test_mode.



3
4
5
# File 'lib/procrastinator/environment.rb', line 3

def test_mode
  @test_mode
end

Instance Method Details

#act(*queue_names) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/procrastinator/environment.rb', line 56

def act(*queue_names)
   unless @test_mode
      raise RuntimeError.new('Procrastinator.act called outside Test Mode. Enable test mode by setting Procrastinator.test_mode = true before running setup')
   end

   if queue_names.empty?
      @queue_workers.each do |worker|
         worker.act
      end
   else
      queue_names.each do |name|
         @queue_workers.find { |worker| worker.name == name }.act
      end
   end
end

#define_queue(name, properties = {}) ⇒ Object

Raises:

  • (ArgumentError)


22
23
24
25
26
# File 'lib/procrastinator/environment.rb', line 22

def define_queue(name, properties={})
   raise ArgumentError.new('queue name cannot be nil') if name.nil?

   @queue_definitions[name] = properties
end

#delay(queue: nil, run_at: Time.now.to_i, expire_at: nil, task:) ⇒ Object

Raises:

  • (ArgumentError)


72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/procrastinator/environment.rb', line 72

def delay(queue: nil, run_at: Time.now.to_i, expire_at: nil, task:)
   raise ArgumentError.new('task may not be nil') if task.nil?
   raise MalformedTaskError.new('the provided task does not support #run method') unless task.respond_to? :run

   # We're checking these on init because it's one of those extremely rare cases where you'd want to know
   # incredibly early, because of the sub-processing. It's a bit belt-and suspenders, but UX is important for
   # devs, too.
   [:success, :fail, :final_fail].each do |method_name|
      if task.respond_to?(method_name) && task.method(method_name).arity <= 0
         raise MalformedTaskError.new("the provided task must accept a parameter to its ##{method_name} method")
      end
   end

   if queue.nil? && @queue_definitions.size > 1
      raise ArgumentError.new("queue must be specified when more than one is registered. Defined queues are: #{queue_definitions.keys.map { |k| ':' + k.to_s }.join(', ')}")
   else
      queue ||= @queue_definitions.keys.first
      raise ArgumentError.new(%Q{there is no "#{queue}" queue registered in this environment}) if @queue_definitions[queue].nil?
   end

   @persister.create_task(queue:          queue,
                          run_at:         run_at.to_i,
                          initial_run_at: run_at.to_i,
                          expire_at:      expire_at.nil? ? nil : expire_at.to_i,
                          task:           YAML.dump(task))
end

#enable_test_modeObject



99
100
101
# File 'lib/procrastinator/environment.rb', line 99

def enable_test_mode
   @test_mode = true
end

#log_dir(path) ⇒ Object



103
104
105
# File 'lib/procrastinator/environment.rb', line 103

def log_dir(path)
   @log_dir = path
end

#log_level(lvl) ⇒ Object



107
108
109
# File 'lib/procrastinator/environment.rb', line 107

def log_level(lvl)
   @log_level = lvl
end

#persister_factory(&block) ⇒ Object



16
17
18
19
20
# File 'lib/procrastinator/environment.rb', line 16

def persister_factory(&block)
   @persister_factory = block

   build_persister
end

#process_prefix(prefix) ⇒ Object



111
112
113
# File 'lib/procrastinator/environment.rb', line 111

def process_prefix(prefix)
   @process_prefix = prefix
end

#spawn_workersObject



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/procrastinator/environment.rb', line 28

def spawn_workers
   if @test_mode
      @queue_definitions.each do |name, props|
         @queue_workers << QueueWorker.new(props.merge(name:      name,
                                                       persister: @persister))
      end
   else
      @queue_definitions.each do |name, props|
         pid = fork do
            build_persister
            worker = QueueWorker.new(props.merge(name:      name,
                                                 persister: @persister,
                                                 log_dir:   @log_dir,
                                                 log_level: @log_level))

            Process.setproctitle("#{@process_prefix ? "#{@process_prefix}-" : ''}#{worker.long_name}") # tODO: add an app name prefix

            monitor_parent(worker)

            worker.work
         end

         Process.detach(pid) unless pid.nil?
         @processes << pid
      end
   end
end