Module: Smash::CloudPowers::WorkflowFactory
- Included in:
- Smash::CloudPowers
- Defined in:
- lib/cloud_powers/workflow_factory.rb
Overview
The WorkflowFactory module provides you with a custom, embeddable workflow
for classes. To do this, it takes a description of the workflow, in
the form of a Hash and injects it into the class' Singleton/Eigan
class. It uses the workflow gem to handle the workflow stuff for now
but after MVP, this will be a roll-our-own implementation, to cut down on
all dependencies possible.
Instance Method Summary collapse
-
#description_to_s(description) ⇒ Object
Takes a description and turns it into a string that would describe the workflow you want to insert.
-
#inject_workflow(description) ⇒ Object
This is the method responsible for injecting the workflow on the instance it is called on.
Instance Method Details
#description_to_s(description) ⇒ Object
Takes a description and turns it into a string that would describe the workflow you want to insert.
Parameters
descriptionHash- of the format { workflow: { states: [ { state_name: { event: :event_name, transitions_to: :transition_to_name } }, { state_name: nil } ] } }
Returns
String
Example
given the description seen in inject_workflow()
puts description_to_s(description)
=>
workflow do state :new do event :build, :transitions_to => :building end state :building do event :run, :transitions_to => :in_progress end state :in_progress do event :post_results, :transitions_to => :done end state :done end Notes
- See inject_workflow()
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/cloud_powers/workflow_factory.rb', line 140 def description_to_s(description) description_string_builder = ['include Workflow', 'workflow do'] description[:workflow][:states].each do |state| state.map do |name, state_description| if state_description.nil? # if this is a final state... description_string_builder << "state :#{name}" else # because it is not a final state, add event information too. description_string_builder.concat([ "state :#{name} do", "event :#{state_description[:event]}, transitions_to: :#{state_description[:transitions_to]}", "end" ]) end end end description_string_builder << "end\n" description_string_builder.join("\n") end |
#inject_workflow(description) ⇒ Object
This is the method responsible for injecting the workflow on the instance it is called on. After this method is called on an instance of some class, you can then access any of the described states as methods on that instance.
Parameters
-
description
Hash- Describe the workflow you want to use. The format follows the actual Workflow Specification(s) from the gem that you would normally write onto the class like normal. -
Example
descriptionHash -
-
this description would give you a workflow that starts in the
newstate and when the #build!() method was called on the object that has this workflow, the state would transition into thebuildingstate. The workflow would then listen for the run!() method call, which would progress the state to thein_progressstate. Next, the workflow would listen for the post_results!() method call. When someone or something calls it, the state will progress to the final state,done, from which no more workflow stuff will happen.description = { workflow: { states: [ { new: { event: :build, transitions_to: :building } }, { building: { event: :run, transitions_to: :in_progress } }, { in_progress: { event: :post_results, transitions_to: :done } }, { done: nil } ] } }
-
Returns
nil
Example
-
build the workflow using the description from above class Job # code code code... def insert_my_workflow(description) class << build_workflow(description) end end
Which would yield this workflow, from the Workflow gem
class Job # all the commented lines below are what `WorkflowFactory#inject_workflow()` # did for you. These lines don't need to actually be in your class. # include Workflow # # workflow do # state :new do # event :build, :transitions_to => :building # end # state :building do # event :run, :transitions_to => :in_progress # end # state :in_progress do # event :post_results, :transitions_to => :done # end # state :done # end end job = Job.new # => #<Job:0x007fdaba8956b0> job.done? # => NoMethodError job.insert_workflow(description) # => nil job.done? # => false job.current_state # => :building
Notes
- See description_to_s()
- TODO: There has got to be a better way, so if any of you have suggestions... The fact that the eval gets evaluated and invoked in the workflow gem is of little comfort, despite how nice the gem is. Long story short, be comfortable with what you're doing.
- see the workflow gem docs and question me if you want some nice ways to really use this module. workflow homepage
95 96 97 98 99 100 101 102 103 |
# File 'lib/cloud_powers/workflow_factory.rb', line 95 def inject_workflow(description) workflow_spec_string = description_to_s(description) begin self.class.class_eval(workflow_spec_string) define_singleton_method(:has_workflow?) { true } rescue Exception => e define_singleton_method(:has_workflow?) { !!(puts e.backtrace) } end end |