batch-kit 0.3
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.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/README.md +165 -0
- data/lib/batch-kit.rb +9 -0
- data/lib/batch-kit/arguments.rb +57 -0
- data/lib/batch-kit/config.rb +517 -0
- data/lib/batch-kit/configurable.rb +68 -0
- data/lib/batch-kit/core_ext/enumerable.rb +97 -0
- data/lib/batch-kit/core_ext/file.rb +69 -0
- data/lib/batch-kit/core_ext/file_utils.rb +103 -0
- data/lib/batch-kit/core_ext/hash.rb +17 -0
- data/lib/batch-kit/core_ext/numeric.rb +17 -0
- data/lib/batch-kit/core_ext/string.rb +88 -0
- data/lib/batch-kit/database.rb +133 -0
- data/lib/batch-kit/database/java_util_log_handler.rb +65 -0
- data/lib/batch-kit/database/log4r_outputter.rb +57 -0
- data/lib/batch-kit/database/models.rb +548 -0
- data/lib/batch-kit/database/schema.rb +229 -0
- data/lib/batch-kit/encryption.rb +7 -0
- data/lib/batch-kit/encryption/java_encryption.rb +178 -0
- data/lib/batch-kit/encryption/ruby_encryption.rb +175 -0
- data/lib/batch-kit/events.rb +157 -0
- data/lib/batch-kit/framework/acts_as_job.rb +197 -0
- data/lib/batch-kit/framework/acts_as_sequence.rb +123 -0
- data/lib/batch-kit/framework/definable.rb +169 -0
- data/lib/batch-kit/framework/job.rb +121 -0
- data/lib/batch-kit/framework/job_definition.rb +105 -0
- data/lib/batch-kit/framework/job_run.rb +145 -0
- data/lib/batch-kit/framework/runnable.rb +235 -0
- data/lib/batch-kit/framework/sequence.rb +87 -0
- data/lib/batch-kit/framework/sequence_definition.rb +38 -0
- data/lib/batch-kit/framework/sequence_run.rb +48 -0
- data/lib/batch-kit/framework/task_definition.rb +89 -0
- data/lib/batch-kit/framework/task_run.rb +53 -0
- data/lib/batch-kit/helpers/date_time.rb +54 -0
- data/lib/batch-kit/helpers/email.rb +198 -0
- data/lib/batch-kit/helpers/html.rb +175 -0
- data/lib/batch-kit/helpers/process.rb +101 -0
- data/lib/batch-kit/helpers/zip.rb +30 -0
- data/lib/batch-kit/job.rb +11 -0
- data/lib/batch-kit/lockable.rb +138 -0
- data/lib/batch-kit/loggable.rb +78 -0
- data/lib/batch-kit/logging.rb +169 -0
- data/lib/batch-kit/logging/java_util_logger.rb +87 -0
- data/lib/batch-kit/logging/log4r_logger.rb +71 -0
- data/lib/batch-kit/logging/null_logger.rb +35 -0
- data/lib/batch-kit/logging/stdout_logger.rb +96 -0
- data/lib/batch-kit/resources.rb +191 -0
- data/lib/batch-kit/sequence.rb +7 -0
- metadata +122 -0
@@ -0,0 +1,157 @@
|
|
1
|
+
class BatchKit
|
2
|
+
|
3
|
+
# Manages batch event notifications and subscriptions, which provide a
|
4
|
+
# useful means of decoupling different components of the batch library.
|
5
|
+
#
|
6
|
+
# The problem we are looking to solve here is that we want our batch jobs,
|
7
|
+
# tasks etc to be able to notify interested parties when something happens
|
8
|
+
# (e.g. a task starts, a job fails, etc) without these event sources needing
|
9
|
+
# to know all the interested parties to notify. We therefore introduce an
|
10
|
+
# intermediary, which is the Events system.
|
11
|
+
#
|
12
|
+
# Interested parties register their interest in specific events or event
|
13
|
+
# classes by subscribing to the events of interest. Framework classes then
|
14
|
+
# notify the Event system when an event occurs, and the event system routes
|
15
|
+
# these notifications on to all registered subscribers.
|
16
|
+
#
|
17
|
+
# One of the problems we need to solve for is how subscribers can define the
|
18
|
+
# scope of their interest. Is it all events of a particular type, regardless
|
19
|
+
# of source? Or are we only interested in events from a specific source (e.g
|
20
|
+
# job or task)?
|
21
|
+
class Events
|
22
|
+
|
23
|
+
# Records subscription details
|
24
|
+
class Subscription
|
25
|
+
|
26
|
+
attr_reader :source, :event, :callback, :raise_on_error
|
27
|
+
|
28
|
+
|
29
|
+
def initialize(source, event, options, callback)
|
30
|
+
@source = source
|
31
|
+
@event = event
|
32
|
+
@raise_on_error = options.fetch(:raise_on_error, true)
|
33
|
+
@callback = callback
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def ===(obj)
|
38
|
+
@source.nil? || # Nil source means match any obj
|
39
|
+
(@source == obj) || # Source is obj
|
40
|
+
(@source === obj) || # obj is an instance of source class
|
41
|
+
(@source.instance_of?(Module) && obj.instance_of?(Class) &&
|
42
|
+
obj.include?(@source)) # Source is a module included by obj
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
class << self
|
50
|
+
|
51
|
+
# @param source [Object] The source of the event
|
52
|
+
# @param event [String] The name of the event
|
53
|
+
# @return [Boolean] whether there are any subscribers for the specified
|
54
|
+
# event.
|
55
|
+
def has_subscribers?(source, event)
|
56
|
+
subscribers.has_key?(event) && subscribers[event].size > 0 &&
|
57
|
+
subscribers[event].find{ |sub| sub === source }
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
# Setup a subscription for a particular event. When a matching event
|
62
|
+
# occurs, the supplied block will be called with the published
|
63
|
+
# arguments.
|
64
|
+
#
|
65
|
+
# @param source [Object] The type of source object from which to
|
66
|
+
# listen for events.
|
67
|
+
# @param event [String] The name of the event to subscribe to.
|
68
|
+
# @param options [Hash] An options hash defining optional settings
|
69
|
+
# for the subscription.
|
70
|
+
# @option options [Fixnum] :position The position within the list to
|
71
|
+
# insert the subscriber. Default is to add to the end of the list.
|
72
|
+
# @param callback [Proc] A block to be invoked when the event occurs.
|
73
|
+
def subscribe(source, event, options = {}, &callback)
|
74
|
+
@log.trace "Adding subscriber for #{source} event '#{event}'" if @log
|
75
|
+
position = options.fetch(:position, -1)
|
76
|
+
if event.is_a?(Array)
|
77
|
+
event.each{ |e| subscribers[e].insert(position, Subscription.new(source, e, options, callback)) }
|
78
|
+
else
|
79
|
+
subscribers[event].insert(position, Subscription.new(source, event, options, callback))
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
# Remove a subscriber
|
85
|
+
#
|
86
|
+
# @param source [Object] The object that is the source of the event
|
87
|
+
# from which to unsubscribe.
|
88
|
+
# @param event [String] The name of the event to unsubscribe from.
|
89
|
+
def unsubscribe(source, event)
|
90
|
+
@log.trace "Removing subscriber(s) for #{source} event '#{event}'" if @log
|
91
|
+
subscribers[event].delete_if{ |sub| sub === source }
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
# Publishes an event to all registered subscribers.
|
96
|
+
#
|
97
|
+
# @param source [Object] The source from which the event has been
|
98
|
+
# generated.
|
99
|
+
# @param event [String] The name of the event that has occurred.
|
100
|
+
# @param payload [*Object] Arguments passed with the event.
|
101
|
+
def publish(source, event, *payload)
|
102
|
+
@log.trace "Publishing event '#{event}' for #{source}" if @log
|
103
|
+
res = true
|
104
|
+
count = 0
|
105
|
+
if subscribers.has_key?(event)
|
106
|
+
subscribers[event].each do |sub|
|
107
|
+
if sub === source
|
108
|
+
begin
|
109
|
+
r = sub.callback.call(source, *payload)
|
110
|
+
count += 1
|
111
|
+
res &&= r
|
112
|
+
rescue StandardError => ex
|
113
|
+
if sub.raise_on_error
|
114
|
+
raise
|
115
|
+
else
|
116
|
+
STDERR.puts "Exception in '#{event}' event listener for #{source}: #{ex}\n" +
|
117
|
+
" at: #{ex.backtrace[0...10].join("\n")}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
@log.debug "Notified #{count} listeners of '#{event}'" if @log
|
123
|
+
end
|
124
|
+
res
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
# Enable/disable event debugging
|
129
|
+
def debug=(dbg)
|
130
|
+
@log = dbg ? LogManager.logger('batch.events') : nil
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
# Dumps a list of events and their subscribers to the logger
|
135
|
+
def dump_subscribers(show_event = nil, log = @log)
|
136
|
+
if log
|
137
|
+
subscribers.each do |event, subs|
|
138
|
+
if show_event.nil? || show_event == event
|
139
|
+
log.info "Subscribers for event '#{event}':"
|
140
|
+
subs.each{ |sub| log.detail sub.inspect }
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
private
|
148
|
+
|
149
|
+
def subscribers
|
150
|
+
@subscribers ||= Hash.new{ |h, k| h[k] = [] }
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
class BatchKit
|
2
|
+
|
3
|
+
# When included into a class, marks the class as a BatchKit job.
|
4
|
+
# The including class has the following class methods added, which act as a
|
5
|
+
# DSL for specifying the job properties and behaviour:
|
6
|
+
# - {ClassMethods#desc desc} A method for setting a description for a
|
7
|
+
# subsequent job or task
|
8
|
+
# - {ClassMethods#job job} Defines a job entry method
|
9
|
+
# - {ClassMethods#task task} Defines a task method
|
10
|
+
# - {ClassMethods#job_definition job_definition} Returns the Job::Definition
|
11
|
+
# object for the including class
|
12
|
+
# - {ClassMethods#on_success on_success} defines a callback to be called if
|
13
|
+
# the job completes successfully.
|
14
|
+
# - {ClassMethods#on_failure on_failure} defines a callback to be called if
|
15
|
+
# the job encounters an unhandled exception.
|
16
|
+
# - {ClassMethods#on_completion} defines a callback to be called when the
|
17
|
+
# job completes.
|
18
|
+
#
|
19
|
+
# Instances of the including class also get the following instance methods:
|
20
|
+
# - {#job} Returns the Job::Definition for the class
|
21
|
+
# - {#job_run} Returns the Job::Run associated with this object instance.
|
22
|
+
module ActsAsJob
|
23
|
+
|
24
|
+
# Define methods to be added to the class that includes this module.
|
25
|
+
module ClassMethods
|
26
|
+
|
27
|
+
# @return The Job::Definition object used to hold attributes of this
|
28
|
+
# job.
|
29
|
+
def job_definition
|
30
|
+
@__job__
|
31
|
+
end
|
32
|
+
alias_method :definition, :job_definition
|
33
|
+
|
34
|
+
|
35
|
+
# Captures a description for the following task or job definition.
|
36
|
+
#
|
37
|
+
# @param desc [String] The description to associate with the next
|
38
|
+
# task or job that is defined.
|
39
|
+
def desc(desc)
|
40
|
+
@__desc__ = desc
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
# Defines the method that is used to run this job.
|
45
|
+
# This may be an existing method, in which case the name of the
|
46
|
+
# method must be passed as the first argument.
|
47
|
+
# Alternatively, a block may be supplied, which will be used to
|
48
|
+
# create the job method.
|
49
|
+
#
|
50
|
+
# @param job_method [Symbol] The name of an existing method that is
|
51
|
+
# to be the job entry point.
|
52
|
+
# @param job_opts [Hash] Options that affect the job definition.
|
53
|
+
# @option job_opts [Symbol] :method_name The name to be assigned to
|
54
|
+
# the job method created from the supplied block. Default is
|
55
|
+
# :execute.
|
56
|
+
# @option job_opts [String] :description A description for the job.
|
57
|
+
def job(job_method = nil, job_opts = @__desc__, &body)
|
58
|
+
# If called as an accessor, just return the @__job__
|
59
|
+
if job_method || job_opts || body
|
60
|
+
unless job_method.is_a?(Symbol)
|
61
|
+
job_opts = job_method
|
62
|
+
job_method = (job_opts && job_opts.is_a?(Hash) &&
|
63
|
+
job_opts[:method_name]) || :execute
|
64
|
+
end
|
65
|
+
|
66
|
+
job_desc = nil
|
67
|
+
if job_opts.is_a?(Hash)
|
68
|
+
job_desc = @__desc__
|
69
|
+
elsif job_opts.is_a?(String)
|
70
|
+
job_desc = job_opts
|
71
|
+
job_opts = {}
|
72
|
+
elsif job_opts.nil?
|
73
|
+
job_opts = {}
|
74
|
+
end
|
75
|
+
@__desc__ = nil
|
76
|
+
|
77
|
+
# Define job method if a body block was supplied
|
78
|
+
define_method(job_method, &body) if body
|
79
|
+
|
80
|
+
opts = job_opts.clone
|
81
|
+
opts[:description] = job_desc unless opts[:description]
|
82
|
+
opts[:method_name] = job_method
|
83
|
+
# The @__job__ instance variable is crated when this module is included
|
84
|
+
@__job__.set_from_options(opts)
|
85
|
+
end
|
86
|
+
@__job__
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
# Defines the method that is used to run a task.
|
91
|
+
# This may be an existing method, in which case the name of the
|
92
|
+
# method must be passed as the first argument.
|
93
|
+
# Alternatively, a block may be supplied, which will be used to
|
94
|
+
# create the task method.
|
95
|
+
#
|
96
|
+
# @param task_method [Symbol] The name for the method that is to be
|
97
|
+
# this task. May be the name of an existing method (in which case
|
98
|
+
# no block should be supplied), or the name to give to the method
|
99
|
+
# that will be created from the supplied block.
|
100
|
+
# @param task_opts [Hash] A hash containing options for the task
|
101
|
+
# being defined.
|
102
|
+
# @option task_opts [Symbol] :method_name The name for the method
|
103
|
+
# if no symbol was provided as the first argument.
|
104
|
+
# @option job_opts [String] :description A description for the task.
|
105
|
+
def task(task_method, task_opts = @__desc__, &body)
|
106
|
+
unless task_method.is_a?(Symbol)
|
107
|
+
task_opts = task_method
|
108
|
+
task_method = task_opts && task_opts[:method_name]
|
109
|
+
end
|
110
|
+
raise ArgumentError, "No method name specified for task" unless task_method
|
111
|
+
|
112
|
+
task_desc = nil
|
113
|
+
if task_opts.is_a?(Hash)
|
114
|
+
task_desc = @__desc__
|
115
|
+
elsif task_opts.is_a?(String)
|
116
|
+
task_desc = task_opts
|
117
|
+
task_opts = {}
|
118
|
+
elsif task_opts.nil?
|
119
|
+
task_opts = {}
|
120
|
+
end
|
121
|
+
@__desc__ = nil
|
122
|
+
|
123
|
+
# Define task method if a body block was supplied
|
124
|
+
define_method(task_method, &body) if body
|
125
|
+
|
126
|
+
opts = task_opts.clone
|
127
|
+
opts[:description] = task_desc unless opts[:description]
|
128
|
+
|
129
|
+
# Create a new TaskDefinition class for the task
|
130
|
+
task_defn = Task::Definition.new(self, task_method)
|
131
|
+
task_defn.set_from_options(opts)
|
132
|
+
task_defn
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
# Defines a handler to be invoked if the job encounters an unhandled
|
137
|
+
# exception.
|
138
|
+
def on_failure(mthd = nil, &blk)
|
139
|
+
Events.subscribe(self, 'job_run.failure'){ |jr, obj, ex| obj.send(mthd, ex) } if mthd
|
140
|
+
Events.subscribe(self, 'job_run.failure'){ |jr, obj, ex| obj.instance_exec(ex, &blk) } if blk
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
# Defines a handler to be invoked if the job ends successfully.
|
145
|
+
def on_success(mthd = nil, &blk)
|
146
|
+
Events.subscribe(self, 'job_run.success'){ |jr, obj| obj.send(mthd) } if mthd
|
147
|
+
Events.subscribe(self, 'job_run.success'){ |jr, obj| obj.instance_exec(&blk) } if blk
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
# Defines a handler to be invoked on completion of the job, whether
|
152
|
+
# the job completes successfully or fails. The handler may be specified
|
153
|
+
# as either a method name and/or via a block. Multiple calls to this
|
154
|
+
# method can be made to register multiple callbacks if desired.
|
155
|
+
#
|
156
|
+
# @param mthd [Symbol] The name of an existing method on the including
|
157
|
+
# class. This method will be called with the Job::Run object that
|
158
|
+
# represents the completing job run.
|
159
|
+
#
|
160
|
+
def on_completion(mthd = nil, &blk)
|
161
|
+
Events.subscribe(self, 'job_run.post-execute'){ |jr, obj, ok| obj.send(mthd, jr) } if mthd
|
162
|
+
Events.subscribe(self, 'job_run.post-execute'){ |jr, obj, ok| obj.instance_exec(jr, &blk) } if blk
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
# Hook used to extend the including class with class methods defined in
|
169
|
+
# the ActsAsJob::ClassMethods module.
|
170
|
+
#
|
171
|
+
# Creates a Job::Definition object to hold details of the job, and stores
|
172
|
+
# it away in a @__job__ class instance variable.
|
173
|
+
def self.included(base)
|
174
|
+
base.extend(ClassMethods)
|
175
|
+
caller.find{ |f| !(f =~ /batch-kit.framework/) } =~ /^((?:[a-zA-Z]:)?[^:]+)/
|
176
|
+
job_file = File.realpath($1)
|
177
|
+
job_defn = Job::Definition.new(base, job_file)
|
178
|
+
base.instance_variable_set :@__job__, job_defn
|
179
|
+
Events.publish(base, 'acts_as_job.included', job_defn)
|
180
|
+
end
|
181
|
+
|
182
|
+
|
183
|
+
# @return [Job::Definition] The JobDefinition for this job instance.
|
184
|
+
def job
|
185
|
+
self.class.job_definition
|
186
|
+
end
|
187
|
+
|
188
|
+
|
189
|
+
# @return [Job::Run] The JobRun for this job instance.
|
190
|
+
def job_run
|
191
|
+
@__job_run__
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
|
@@ -0,0 +1,123 @@
|
|
1
|
+
class BatchKit
|
2
|
+
|
3
|
+
# When included into a class, marks the class as a BatchKit sequence.
|
4
|
+
# The including class has the following class methods added, which act as a
|
5
|
+
# DSL for specifying the sequence properties and behaviour:
|
6
|
+
# - {ClassMethods#desc desc} A method for setting a description for a
|
7
|
+
# subsequent sequence
|
8
|
+
# - {ClassMethods#sequence sequence} Defines a sequence entry method
|
9
|
+
# - {ClassMethods#sequence_definition sequence_definition} Returns the
|
10
|
+
# Sequence::Definition object for the including class
|
11
|
+
# - {ClassMethods#on_success on_success} defines a callback to be called if
|
12
|
+
# the sequence completes successfully.
|
13
|
+
# - {ClassMethods#on_failure on_failure} defines a callback to be called if
|
14
|
+
# the sequence encounters an unhandled exception.
|
15
|
+
#
|
16
|
+
# Instances of the including class also get the following instance methods:
|
17
|
+
# - {#sequence} Returns the Sequence::Definition for the class
|
18
|
+
# - {#sequence_run} Returns the Sequence::Run associated with this object instance.
|
19
|
+
module ActsAsSequence
|
20
|
+
|
21
|
+
# Define methods to be added to the class that includes this module.
|
22
|
+
module ClassMethods
|
23
|
+
|
24
|
+
# @return The Sequence::Definition object used to hold attributes of this
|
25
|
+
# sequence.
|
26
|
+
def sequence_definition
|
27
|
+
@__sequence__
|
28
|
+
end
|
29
|
+
alias_method :definition, :sequence_definition
|
30
|
+
|
31
|
+
|
32
|
+
# Captures a description for the following sequence definition.
|
33
|
+
#
|
34
|
+
# @param desc [String] The description to associate with the next
|
35
|
+
# sequence, job, or task that is defined.
|
36
|
+
def desc(desc)
|
37
|
+
@__desc__ = desc
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
# Defines the method that is used to run this job.
|
42
|
+
# This may be an existing method, in which case the name of the
|
43
|
+
# method must be passed as the first argument.
|
44
|
+
# Alternatively, a block may be supplied, which will be used to
|
45
|
+
# create the job method.
|
46
|
+
#
|
47
|
+
# @param sequence_method [Symbol] The name of an existing method that is
|
48
|
+
# to be the sequence entry point.
|
49
|
+
# @param sequence_opts [Hash] Options that affect the sequence definition.
|
50
|
+
# @option sequence_opts [Symbol] :method_name The name to be assigned to
|
51
|
+
# the sequence method created from the supplied block. Default is
|
52
|
+
# :execute.
|
53
|
+
# @option sequence_opts [String] :description A description for the sequence.
|
54
|
+
def sequence(sequence_method = nil, sequence_opts = @__desc__, &body)
|
55
|
+
# If called as an accessor, just return the @__sequence__
|
56
|
+
if sequence_method || sequence_opts || body
|
57
|
+
unless sequence_method.is_a?(Symbol)
|
58
|
+
sequence_opts = sequence_method
|
59
|
+
sequence_method = (sequence_opts && sequence_opts.is_a?(Hash) &&
|
60
|
+
sequence_opts[:method_name]) || :execute
|
61
|
+
end
|
62
|
+
|
63
|
+
sequence_desc = nil
|
64
|
+
if sequence_opts.is_a?(Hash)
|
65
|
+
sequence_desc = @__desc__
|
66
|
+
elsif sequence_opts.is_a?(String)
|
67
|
+
sequence_desc = sequence_opts
|
68
|
+
sequence_opts = {}
|
69
|
+
elsif sequence_opts.nil?
|
70
|
+
sequence_opts = {}
|
71
|
+
end
|
72
|
+
@__desc__ = nil
|
73
|
+
|
74
|
+
# Define sequence method if a body block was supplied
|
75
|
+
define_method(sequence_method, &body) if body
|
76
|
+
|
77
|
+
opts = sequence_opts.clone
|
78
|
+
opts[:description] = sequence_desc unless opts[:description]
|
79
|
+
opts[:method_name] = sequence_method
|
80
|
+
# The @__sequence__ instance variable is crated when this module is included
|
81
|
+
@__sequence__.set_from_options(opts)
|
82
|
+
end
|
83
|
+
@__sequence__
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
# Hook used to extend the including class with class methods defined in
|
90
|
+
# the ActsAsSequence::ClassMethods module.
|
91
|
+
#
|
92
|
+
# Creates a Sequence::Definition object to hold details of the sequence,
|
93
|
+
# and stores it away in a @__sequence__ class instance variable.
|
94
|
+
def self.included(base)
|
95
|
+
base.extend(ClassMethods)
|
96
|
+
caller.find{ |f| !(f =~ /batch.framework/) } =~ /^((?:[a-zA-Z]:)?[^:]+)/
|
97
|
+
sequence_file = File.realpath($1)
|
98
|
+
sequence_defn = Sequence::Definition.new(base, sequence_file)
|
99
|
+
base.instance_variable_set :@__sequence__, sequence_defn
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
def parallel
|
104
|
+
# TODO: Implement running contents of block in parallel
|
105
|
+
yield
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
# @return [Sequence::Definition] The SequenceDefinition for this Sequence instance.
|
110
|
+
def sequence
|
111
|
+
self.class.sequence_definition
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
# @return [Sequence::Run] The SequenceRun for this Sequence instance.
|
116
|
+
def sequence_run
|
117
|
+
@__sequence_run__
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|