glider 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4aa4101f0537f562aa326ba31408d9ff2035b08a
4
+ data.tar.gz: 9cf46b6473470aa0029b7b599c8b98763c228abb
5
+ SHA512:
6
+ metadata.gz: 14458f9f29b9c9f1ab8032d73ae189811c1cfe6448a7e5b712545df7764783ca301ba722defe2076950d6e32f0109b602162e7b697b25293a5b068ac3f39879f
7
+ data.tar.gz: 72306154571324a022b22c3e09ddee1778602b4362e8cf985dee25e8e9a74f7a71803aa6fe2f3d600938b4c6447121bad60025ad5990b026ba27730efe6601f4
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'pry'
4
+ gem 'aws-sdk'
5
+ gem 'colorize'
6
+ gem 'activesupport', '~> 4.0.1', require: 'active_support/inflector'
data/Gemfile.lock ADDED
@@ -0,0 +1,40 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ activesupport (4.0.1)
5
+ i18n (~> 0.6, >= 0.6.4)
6
+ minitest (~> 4.2)
7
+ multi_json (~> 1.3)
8
+ thread_safe (~> 0.1)
9
+ tzinfo (~> 0.3.37)
10
+ atomic (1.1.14)
11
+ aws-sdk (1.26.0)
12
+ json (~> 1.4)
13
+ nokogiri (>= 1.4.4, < 1.6.0)
14
+ uuidtools (~> 2.1)
15
+ coderay (1.0.9)
16
+ colorize (0.6.0)
17
+ i18n (0.6.5)
18
+ json (1.8.1)
19
+ method_source (0.8.2)
20
+ minitest (4.7.5)
21
+ multi_json (1.8.2)
22
+ nokogiri (1.5.10)
23
+ pry (0.9.12.2)
24
+ coderay (~> 1.0.5)
25
+ method_source (~> 0.8)
26
+ slop (~> 3.4)
27
+ slop (3.4.6)
28
+ thread_safe (0.1.3)
29
+ atomic
30
+ tzinfo (0.3.38)
31
+ uuidtools (2.1.4)
32
+
33
+ PLATFORMS
34
+ ruby
35
+
36
+ DEPENDENCIES
37
+ activesupport (~> 4.0.1)
38
+ aws-sdk
39
+ colorize
40
+ pry
data/README.md ADDED
@@ -0,0 +1,36 @@
1
+ Useful documentation links:
2
+
3
+ http://docs.aws.amazon.com/amazonswf/latest/apireference/API_RespondDecisionTaskCompleted.html
4
+
5
+ http://docs.aws.amazon.com/amazonswf/latest/apireference/API_HistoryEvent.html
6
+
7
+ http://docs.aws.amazon.com/amazonswf/latest/developerguide/swf-dev-workflow-exec-lifecycle.html
8
+
9
+ USEFUL TO DECIDE WHAT TO PASS TO THE METHOD
10
+
11
+ INFO 15:16:05 Starting workers for ["hello_world-1.0"] and ["say_hi-1.0"]
12
+ INFO 15:16:05 Startig worker for say_hi (class: MySWF)
13
+ INFO 15:16:42 Processing decision task workflow_id=bb235559-9ee6-4a80-96c5-9eed168046d5
14
+ INFO 15:16:42 say_hi event=workflow_execution_started data=ALOHA
15
+ WARN 15:16:42 No result for decision_task_scheduled, attributes: {:task_list=>"say_hi", :start_to_close_timeout=>5}
16
+ WARN 15:16:42 say_hi event=decision_task_scheduled data=
17
+ WARN 15:16:42 No result for decision_task_started, attributes: {:identity=>"dmb.local:49424", :scheduled_event_id=>2}
18
+ WARN 15:16:42 say_hi event=decision_task_started data=
19
+ WARN 15:16:42 No result for decision_task_timed_out, attributes: {:timeout_type=>"START_TO_CLOSE", :scheduled_event_id=>2, :started_event_id=>3}
20
+ WARN 15:16:42 say_hi event=decision_task_timed_out data=
21
+ WARN 15:16:42 No result for decision_task_scheduled, attributes: {:task_list=>"say_hi", :start_to_close_timeout=>5}
22
+ WARN 15:16:42 say_hi event=decision_task_scheduled data=
23
+ WARN 15:16:42 No result for decision_task_started, attributes: {:identity=>"dmb.local:49461", :scheduled_event_id=>5}
24
+ WARN 15:16:42 say_hi event=decision_task_started data=
25
+ DEBUG 15:16:42 [{:decision_type=>"CompleteWorkflowExecution", :complete_workflow_execution_decision_attributes=>{}}]
26
+
27
+ terminations dont trigger decisions
28
+
29
+
30
+ TODO:
31
+
32
+ Proces monitoring
33
+ activity task signaling
34
+
35
+ Exec scoped logger
36
+ instance methods
@@ -0,0 +1,129 @@
1
+
2
+ taken from docs.aws.amazon.com/amazonswf/latest/apireference/API_HistoryEvent.html
3
+
4
+
5
+ WorkflowExecutionStarted:
6
+ The workflow execution was started.
7
+
8
+ WorkflowExecutionCompleted:
9
+ The workflow execution was closed due to successful completion.
10
+
11
+ WorkflowExecutionFailed:
12
+ The workflow execution closed due to a failure.
13
+
14
+ WorkflowExecutionTimedOut:
15
+ The workflow execution was closed because a time out was exceeded.
16
+
17
+ WorkflowExecutionCanceled:
18
+ The workflow execution was successfully canceled and closed.
19
+
20
+ WorkflowExecutionTerminated:
21
+ The workflow execution was terminated.
22
+
23
+ WorkflowExecutionContinuedAsNew:
24
+ The workflow execution was closed and a new execution of the same type was created with the same workflowId.
25
+
26
+ WorkflowExecutionCancelRequested:
27
+ A request to cancel this workflow execution was made.
28
+
29
+ DecisionTaskScheduled:
30
+ A decision task was scheduled for the workflow execution.
31
+
32
+ DecisionTaskStarted:
33
+ The decision task was dispatched to a decider.
34
+
35
+ DecisionTaskCompleted:
36
+ The decider successfully completed a decision task by calling RespondDecisionTaskCompleted.
37
+
38
+ DecisionTaskTimedOut:
39
+ The decision task timed out.
40
+
41
+ ActivityTaskScheduled:
42
+ An activity task was scheduled for execution.
43
+
44
+ ScheduleActivityTaskFailed:
45
+ Failed to process ScheduleActivityTask decision. This happens when the decision is not configured properly, for example the activity type specified is not registered.
46
+
47
+ ActivityTaskStarted:
48
+ The scheduled activity task was dispatched to a worker.
49
+
50
+ ActivityTaskCompleted:
51
+ An activity worker successfully completed an activity task by calling RespondActivityTaskCompleted.
52
+
53
+ ActivityTaskFailed:
54
+ An activity worker failed an activity task by calling RespondActivityTaskFailed.
55
+
56
+ ActivityTaskTimedOut:
57
+ The activity task timed out.
58
+
59
+ ActivityTaskCanceled:
60
+ The activity task was successfully canceled.
61
+
62
+ ActivityTaskCancelRequested:
63
+ A RequestCancelActivityTask decision was received by the system.
64
+
65
+ RequestCancelActivityTaskFailed:
66
+ Failed to process RequestCancelActivityTask decision. This happens when the decision is not configured properly.
67
+
68
+ WorkflowExecutionSignaled:
69
+ An external signal was received for the workflow execution.
70
+
71
+ MarkerRecorded:
72
+ A marker was recorded in the workflow history as the result of a RecordMarker decision.
73
+
74
+ TimerStarted:
75
+ A timer was started for the workflow execution due to a StartTimer decision.
76
+
77
+ StartTimerFailed:
78
+ Failed to process StartTimer decision. This happens when the decision is not configured properly, for example a timer already exists with the specified timer Id.
79
+
80
+ TimerFired:
81
+ A timer, previously started for this workflow execution, fired.
82
+
83
+ TimerCanceled:
84
+ A timer, previously started for this workflow execution, was successfully canceled.
85
+
86
+ CancelTimerFailed:
87
+ Failed to process CancelTimer decision. This happens when the decision is not configured properly, for example no timer exists with the specified timer Id.
88
+
89
+ StartChildWorkflowExecutionInitiated:
90
+ A request was made to start a child workflow execution.
91
+
92
+ StartChildWorkflowExecutionFailed:
93
+ Failed to process StartChildWorkflowExecution decision. This happens when the decision is not configured properly, for example the workflow type specified is not registered.
94
+
95
+ ChildWorkflowExecutionStarted:
96
+ A child workflow execution was successfully started.
97
+
98
+ ChildWorkflowExecutionCompleted:
99
+ A child workflow execution, started by this workflow execution, completed successfully and was closed.
100
+
101
+ ChildWorkflowExecutionFailed:
102
+ A child workflow execution, started by this workflow execution, failed to complete successfully and was closed.
103
+
104
+ ChildWorkflowExecutionTimedOut:
105
+ A child workflow execution, started by this workflow execution, timed out and was closed.
106
+
107
+ ChildWorkflowExecutionCanceled:
108
+ A child workflow execution, started by this workflow execution, was canceled and closed.
109
+
110
+ ChildWorkflowExecutionTerminated:
111
+ A child workflow execution, started by this workflow execution, was terminated.
112
+
113
+ SignalExternalWorkflowExecutionInitiated:
114
+ A request to signal an external workflow was made.
115
+
116
+ ExternalWorkflowExecutionSignaled:
117
+ A signal, requested by this workflow execution, was successfully delivered to the target external workflow execution.
118
+
119
+ SignalExternalWorkflowExecutionFailed:
120
+ The request to signal an external workflow execution failed.
121
+
122
+ RequestCancelExternalWorkflowExecutionInitiated:
123
+ A request was made to request the cancellation of an external workflow execution.
124
+
125
+ ExternalWorkflowExecutionCancelRequested:
126
+ Request to cancel an external workflow execution was successfully delivered to the target execution.
127
+
128
+ RequestCancelExternalWorkflowExecutionFailed:
129
+ Request to cancel an external workflow execution failed.
data/lib/glider.rb ADDED
@@ -0,0 +1,11 @@
1
+ $LOAD_PATH << File.dirname(__FILE__)
2
+
3
+ require 'pry'
4
+
5
+ require 'glider/utils'
6
+
7
+ require 'glider/component'
8
+ require 'glider/process_manager'
9
+
10
+ require 'glider/workflows'
11
+ require 'glider/activities'
@@ -0,0 +1,69 @@
1
+ # isolates the common needed tasks of other elemtns
2
+
3
+ module Glider
4
+
5
+ class Component
6
+ class << self
7
+
8
+ def activities
9
+ @activities ||= []
10
+ end
11
+
12
+ def register_activity(name, version, options={})
13
+ default_options = {
14
+ :default_task_list => name.to_s,
15
+ :default_task_schedule_to_start_timeout => :none,
16
+ :default_task_start_to_close_timeout => 60,
17
+ :default_task_schedule_to_close_timeout => :none,
18
+ :default_task_heartbeat_timeout => :none
19
+
20
+ }
21
+
22
+ options = default_options.merge options
23
+
24
+ begin
25
+ activity_type = domain.activity_types.create name.to_s, version, options
26
+ rescue AWS::SimpleWorkflow::Errors::TypeAlreadyExistsFault
27
+ # already registered
28
+ activity_type = domain.activity_types[name.to_s, version]
29
+ end
30
+ workers.times do
31
+ ProcessManager.register_worker loop_block_for_activity(activity_type)
32
+ end
33
+ end
34
+
35
+
36
+
37
+ def loop_block_for_activity(activity_type)
38
+ Proc.new do
39
+ $0 = "ruby #{activity_type.name}-#{activity_type.version}"
40
+ signal_handling
41
+ Glider.logger.info "Startig worker for #{activity_type.name} activity (pid #{Process.pid})"
42
+ begin
43
+ domain.activity_tasks.poll activity_type.name do |activity_task|
44
+ task_lock! do
45
+ begin
46
+ workflow_id = activity_task.workflow_execution.workflow_id
47
+ Glider.logger.info "Executing activity=#{activity_type.name} workflow_id=#{workflow_id}"
48
+ target_instance = self.new activity_task
49
+ activity_result = target_instance.send activity_type.name, activity_task.input
50
+ activity_task.complete! result: activity_result.to_s
51
+ rescue AWS::SimpleWorkflow::ActivityTask::CancelRequestedError
52
+ # cleanup after ourselves
53
+ activity_task.cancel!
54
+ end
55
+ end
56
+ end
57
+ rescue AWS::SimpleWorkflow::Errors::UnknownResourceFault
58
+ $logger.error "An action relating to an expired workflow was sent. Probably the activity took longer than the execution timeout span. Killing activity process."
59
+ exit 1
60
+ end
61
+ end
62
+ end
63
+
64
+
65
+ end
66
+
67
+ end
68
+
69
+ end
@@ -0,0 +1,67 @@
1
+ # isolates the common needed tasks of other elemtns
2
+
3
+ module Glider
4
+
5
+ class Component
6
+
7
+ attr_reader :task, :event
8
+
9
+ def initialize(task, event=nil)
10
+ @task = task
11
+ @event = event
12
+ end
13
+
14
+
15
+ class << self
16
+
17
+ def task_lock!
18
+ @in_task = true
19
+ yield
20
+ ensure
21
+ @in_task = false
22
+ Process.exit! 0 if @time_to_exit # in case an exit signal was received during task processing
23
+ end
24
+
25
+ def graceful_exit
26
+ if @in_task
27
+ @time_to_exit = true
28
+ else
29
+ Process.exit! 0
30
+ end
31
+ end
32
+
33
+ def signal_handling
34
+ Signal.trap('USR1') do
35
+ graceful_exit
36
+ end
37
+ end
38
+
39
+ def swf
40
+ @swf ||= AWS::SimpleWorkflow.new
41
+ end
42
+
43
+ # both setter and getter
44
+ def workers(workers_count=nil)
45
+ workers_count ? @workers = workers_count : @workers ||= 1
46
+ end
47
+
48
+ # both setter and getter
49
+ def domain(domain_name=nil, retention_period: 10)
50
+ if domain_name
51
+ begin
52
+ @domain = swf.domains[domain_name.to_s]
53
+ @domain.status
54
+ rescue AWS::SimpleWorkflow::Errors::UnknownResourceFault => e
55
+ # create it if necessary
56
+ @domain = swf.domains.create(domain_name.to_s, retention_period)
57
+ end
58
+ else
59
+ @domain
60
+ end
61
+ end
62
+
63
+ end
64
+
65
+ end
66
+
67
+ end
@@ -0,0 +1,19 @@
1
+ module Glider
2
+
3
+ def Glider.logger
4
+ $logger ||= Logger.new STDOUT
5
+ end
6
+
7
+ def Glider.execute(domain_name, workflow_name, version, input)
8
+ swf = AWS::SimpleWorkflow.new
9
+ domain = swf.domains[domain_name.to_s]
10
+ domain.workflow_types[workflow_name.to_s, version].start_execution input: input, task_start_to_close_timeout: 5
11
+ end
12
+
13
+ def Glider.signal(domain_name, workflow_id, signal_name, options={})
14
+ swf = AWS::SimpleWorkflow.new
15
+ domain = swf.domains[domain_name.to_s]
16
+ workflow_execution = domain.workflow_executions.with_workflow_id(workflow_id).with_status(:open).first
17
+ workflow_execution.signal signal_name.to_s, options
18
+ end
19
+ end
@@ -0,0 +1,146 @@
1
+ # isolates the common needed tasks of other elemtns
2
+
3
+ module Glider
4
+
5
+ class Component
6
+
7
+
8
+
9
+ class << self
10
+ def workflows
11
+ @workflows ||= []
12
+ end
13
+
14
+ def register_workflow(name, version, options={})
15
+
16
+ default_options = {
17
+ :default_task_list => name.to_s,
18
+ :default_child_policy => :request_cancel,
19
+ :default_task_start_to_close_timeout => 10, # decider timeout
20
+ :default_execution_start_to_close_timeout => 120
21
+ }
22
+ options = default_options.merge options
23
+ begin
24
+ workflow_type = domain.workflow_types.create name.to_s, version, options
25
+ rescue AWS::SimpleWorkflow::Errors::TypeAlreadyExistsFault
26
+ # already registered
27
+ workflow_type = domain.workflow_types[name.to_s, version]
28
+ end
29
+ workers.times do
30
+ ProcessManager.register_worker loop_block_for_workflow(workflow_type)
31
+ end
32
+ end
33
+
34
+ # let's us determine if :decised_task_started should be called :workflow_execution_started
35
+ def has_previous_decisions?(workflow_execution)
36
+ workflow_execution.history_events.each do |event|
37
+ event_type = ActiveSupport::Inflector.underscore(event.event_type).to_sym
38
+ return true if event_type == :decision_task_completed
39
+ end
40
+ return false
41
+ end
42
+
43
+ def should_call_workflow_target?(event_name, workflow_execution)
44
+ case event_name
45
+ when :activity_task_scheduled,
46
+ :activity_task_started,
47
+ :decision_task_scheduled,
48
+ :decision_task_started,
49
+ :decision_task_completed,
50
+ :marker_recorded,
51
+ :timer_started,
52
+ :start_child_workflow_execution_initiated,
53
+ :start_child_workflow_execution_started,
54
+ :signal_external_workflow_execution_initiated,
55
+ :request_cancel_external_workflow_execution_initiated
56
+
57
+ Glider.logger.debug "Skipping decider call event=#{event_name} workflow_id=#{workflow_execution.workflow_id}"
58
+ return false
59
+ else
60
+ return true
61
+ end
62
+ end
63
+
64
+ def workflow_data_for(event_name, event)
65
+ case event_name
66
+ when :workflow_execution_started #:decision_task_scheduled
67
+ event.attributes.input
68
+ when :workflow_execution_signaled
69
+ begin event.attributes.input rescue nil end
70
+ when :activity_task_completed
71
+ begin event.attributes.result rescue nil end
72
+ else
73
+ begin
74
+ event.attributes.result
75
+ rescue
76
+ Glider.logger.debug "no input or result in event, data will be nil event=#{event_name} attributes=#{event.attributes.to_h}"
77
+ nil
78
+ end
79
+ end
80
+ end
81
+
82
+ # used for timeouts and activity task completed
83
+ def activity_name_for(task, event)
84
+ # taken from SimplerWorkflow
85
+ completed_event = task.workflow_execution.events.reverse_order.find do |e|
86
+ e.id == event.attributes.scheduled_event_id
87
+ end
88
+ activity_name = completed_event.attributes.activity_type.name
89
+ inflected_name = ActiveSupport::Inflector.underscore activity_name
90
+ end
91
+
92
+ def process_decision_task(workflow_type, task)
93
+ workflow_id = task.workflow_execution.workflow_id
94
+ Glider.logger.info "Deciding workflow=#{workflow_type.name} workflow_id=#{workflow_id}"
95
+ task.new_events.each do |event|
96
+ event_name = ActiveSupport::Inflector.underscore(event.event_type).to_sym
97
+ if should_call_workflow_target? event_name, task.workflow_execution
98
+ target_instance = self.new task, event
99
+ data = workflow_data_for(event_name, event)
100
+ # convert signals to event names!
101
+ case event_name
102
+ when :workflow_execution_signaled
103
+ event_name = "#{event.attributes.signal_name}_signal".to_sym
104
+ when :activity_task_completed
105
+ event_name = "#{activity_name_for(task, event)}_activity_completed".to_sym
106
+ when :activity_task_timed_out
107
+ event_name = "#{activity_name_for(task, event)}_activity_timed_out".to_sym
108
+ end
109
+
110
+ target_instance.send workflow_type.name, event_name, event, data
111
+
112
+
113
+ # ensure proper response was given (aka a decision taken)
114
+ decisions = task.instance_eval {@decisions}
115
+ Glider.logger.debug decisions
116
+ if decisions.length == 0 && !task.responded?
117
+ # the decider didn't add any decision
118
+ Glider.logger.warn "No decision made workflow=#{workflow_type.name} workflow_id=#{task.workflow_execution.workflow_id}"
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ def loop_block_for_workflow(workflow_type)
125
+ Proc.new do
126
+ $0 = "ruby #{workflow_type.name}-#{workflow_type.version}"
127
+ signal_handling
128
+ Glider.logger.info "Startig worker for #{workflow_type.name} (pid #{Process.pid})"
129
+ begin
130
+ domain.decision_tasks.poll workflow_type.name do |decision_task|
131
+ task_lock! do
132
+ process_decision_task workflow_type, decision_task
133
+ end
134
+ end
135
+ rescue AWS::SimpleWorkflow::Errors::UnknownResourceFault
136
+ $logger.error "An action relating to an expired decision was sent. Probably the decider took longer than the decision timeout span. Killing decider process."
137
+ exit 1
138
+ end
139
+ end
140
+ end
141
+
142
+ end
143
+
144
+ end
145
+
146
+ end
data/readme.md ADDED
@@ -0,0 +1,36 @@
1
+ Useful documentation links:
2
+
3
+ http://docs.aws.amazon.com/amazonswf/latest/apireference/API_RespondDecisionTaskCompleted.html
4
+
5
+ http://docs.aws.amazon.com/amazonswf/latest/apireference/API_HistoryEvent.html
6
+
7
+ http://docs.aws.amazon.com/amazonswf/latest/developerguide/swf-dev-workflow-exec-lifecycle.html
8
+
9
+ USEFUL TO DECIDE WHAT TO PASS TO THE METHOD
10
+
11
+ INFO 15:16:05 Starting workers for ["hello_world-1.0"] and ["say_hi-1.0"]
12
+ INFO 15:16:05 Startig worker for say_hi (class: MySWF)
13
+ INFO 15:16:42 Processing decision task workflow_id=bb235559-9ee6-4a80-96c5-9eed168046d5
14
+ INFO 15:16:42 say_hi event=workflow_execution_started data=ALOHA
15
+ WARN 15:16:42 No result for decision_task_scheduled, attributes: {:task_list=>"say_hi", :start_to_close_timeout=>5}
16
+ WARN 15:16:42 say_hi event=decision_task_scheduled data=
17
+ WARN 15:16:42 No result for decision_task_started, attributes: {:identity=>"dmb.local:49424", :scheduled_event_id=>2}
18
+ WARN 15:16:42 say_hi event=decision_task_started data=
19
+ WARN 15:16:42 No result for decision_task_timed_out, attributes: {:timeout_type=>"START_TO_CLOSE", :scheduled_event_id=>2, :started_event_id=>3}
20
+ WARN 15:16:42 say_hi event=decision_task_timed_out data=
21
+ WARN 15:16:42 No result for decision_task_scheduled, attributes: {:task_list=>"say_hi", :start_to_close_timeout=>5}
22
+ WARN 15:16:42 say_hi event=decision_task_scheduled data=
23
+ WARN 15:16:42 No result for decision_task_started, attributes: {:identity=>"dmb.local:49461", :scheduled_event_id=>5}
24
+ WARN 15:16:42 say_hi event=decision_task_started data=
25
+ DEBUG 15:16:42 [{:decision_type=>"CompleteWorkflowExecution", :complete_workflow_execution_decision_attributes=>{}}]
26
+
27
+ terminations dont trigger decisions
28
+
29
+
30
+ TODO:
31
+
32
+ Proces monitoring
33
+ activity task signaling
34
+
35
+ Exec scoped logger
36
+ instance methods
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: glider
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - David Pelaez
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 4.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: 4.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: jeweler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.8.7
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 1.8.7
69
+ description: Minimal opinionated wrapper around SimpleWorkflow
70
+ email: david@vlipco.co
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files:
74
+ - README.md
75
+ files:
76
+ - Gemfile
77
+ - Gemfile.lock
78
+ - docs/event_names.md
79
+ - lib/glider.rb
80
+ - lib/glider/activities.rb
81
+ - lib/glider/component.rb
82
+ - lib/glider/utils.rb
83
+ - lib/glider/workflows.rb
84
+ - readme.md
85
+ - README.md
86
+ homepage: http://github.com/vlipco/glider
87
+ licenses:
88
+ - MIT
89
+ metadata: {}
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 2.1.9
107
+ signing_key:
108
+ specification_version: 4
109
+ summary: Minimal opinionated wrapper around SimpleWorkflow
110
+ test_files: []