dalliance 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+
6
+ .DS_Store
7
+ *.log
8
+ *.sqlite
9
+
10
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in dalliance.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2012 Annkissam
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,39 @@
1
+ = dalliance
2
+
3
+ Opinionated background processing for ActiveRecord w/ delayed_job & state_machine
4
+
5
+ A simple wrapper for asynchronous processing w/ error handling & a progress_meter
6
+
7
+ == Getting Started
8
+
9
+ In your Gemfile:
10
+
11
+ gem "dalliance"
12
+
13
+ In your model:
14
+
15
+ class Model < ActiveRecord::Base
16
+ dalliance :process_method
17
+ end
18
+
19
+ process_method is the name of the method to invoke for background processing
20
+ to kick it off just call dalliance_background_process
21
+
22
+ Handle your migrations:
23
+
24
+ rails g dalliance:progress_meter
25
+
26
+ rails g dalliance:update model_name
27
+
28
+ == ProgressMeter
29
+
30
+ Create a method called dalliance_progress_meter_total_count
31
+ (or provide the dalliance_progress_meter_total_count_method option)
32
+
33
+ Inside process_method call progress_meter.increment! after each iteration
34
+
35
+ In your views you can then call dalliance_progress to get feedback on your asynchronous process
36
+
37
+ == Copyright
38
+
39
+ Copyright (c) 2012 Annkissam. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ #RSPEC
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new('spec')
7
+
8
+ task :default => :spec
data/dalliance.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "dalliance/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "dalliance"
7
+ s.version = Dalliance::VERSION::STRING
8
+ s.authors = ["Eric Sullivan"]
9
+ s.email = ["eric.sullivan@annkissam.com"]
10
+ s.homepage = "https://github.com/annkissam/dalliance"
11
+ s.summary = Dalliance::VERSION::SUMMARY
12
+ s.description = %q{ Opinionated background processing for ActiveRecord w/ delayed_job & state_machine }
13
+
14
+ s.rubyforge_project = "dalliance"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency('activerecord', '>= 3.0.0')
22
+ s.add_dependency('activesupport', '>= 3.0.0')
23
+
24
+ s.add_dependency('delayed_job', '>= 2.0.0')
25
+ s.add_dependency('state_machine')
26
+
27
+ s.add_development_dependency 'rspec'
28
+ s.add_development_dependency 'delayed_job_active_record'
29
+ s.add_development_dependency 'sqlite3'
30
+ end
@@ -0,0 +1,43 @@
1
+ require 'active_record'
2
+
3
+ module Dalliance
4
+ class ProgressMeter < ::ActiveRecord::Base
5
+ self.table_name = 'dalliance_progress_meters'
6
+
7
+ belongs_to :dalliance_progress_model, :polymorphic => true
8
+
9
+ validates_presence_of :dalliance_progress_model
10
+
11
+ #current_count should max out at total_count, but we'll allow you to miscount...
12
+ validates_numericality_of :current_count, :only_integer => true, :greater_than_or_equal_to => 0#, :less_than_or_equal_to => Proc.new(&:total_count)
13
+ validates_numericality_of :total_count, :only_integer => true, :greater_than => 0
14
+ validates_numericality_of :progress, :only_integer => true, :greater_than_or_equal_to => 0, :less_than_or_equal_to => 100
15
+
16
+ def current_count
17
+ self[:current_count] ||= 0
18
+ end
19
+
20
+ def total_count
21
+ self[:total_count] ||= 1
22
+ end
23
+
24
+ before_validation :calculate_progress
25
+
26
+ def calculate_progress
27
+ begin
28
+ self.progress = (current_count.to_f / total_count.to_f * 100).to_i
29
+
30
+ #Handle an incorrect total_count...
31
+ self.progress = 100 if progress > 100
32
+ rescue
33
+ #what, are you diving by zero?
34
+ self.progress = 0
35
+ end
36
+ end
37
+
38
+ def increment!
39
+ self.current_count += 1
40
+ self.save!
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,13 @@
1
+ module Dalliance
2
+ module VERSION
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ TINY = 1
6
+ PRE = nil
7
+
8
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
9
+
10
+ SUMMARY = "dalliance #{STRING}"
11
+ end
12
+ end
13
+
data/lib/dalliance.rb ADDED
@@ -0,0 +1,139 @@
1
+ require 'dalliance/version'
2
+
3
+ require 'dalliance/progress_meter'
4
+
5
+ module Dalliance
6
+ extend ActiveSupport::Concern
7
+
8
+ class << self
9
+ def options
10
+ @options ||= {
11
+ :background_processing => true,
12
+ :dalliance_progress_meter_total_count_method => :dalliance_progress_meter_total_count
13
+ }
14
+ end
15
+
16
+ def background_processing?
17
+ options[:background_processing]
18
+ end
19
+
20
+ def configure
21
+ yield(self) if block_given?
22
+ end
23
+ end
24
+
25
+ included do
26
+ has_one :dalliance_progress_meter, :as => :dalliance_progress_model, :class_name => '::Dalliance::ProgressMeter'
27
+
28
+ serialize :dalliance_error_hash, Hash
29
+
30
+ #BEGIN state_machine(s)
31
+ scope :dalliance_pending, where(:dalliance_status => 'pending')
32
+ scope :dalliance_processing, where(:dalliance_status => 'processing')
33
+ scope :dalliance_processing_error, where(:dalliance_status => 'processing_error')
34
+ scope :dalliance_completed, where(:dalliance_status => 'completed')
35
+
36
+ state_machine :dalliance_status, :initial => :pending do
37
+ state :pending
38
+ state :processing
39
+ state :processing_error
40
+ state :completed
41
+
42
+ event :queue_dalliance do
43
+ transition :processing_error => :pending
44
+ end
45
+
46
+ event :start_dalliance do
47
+ transition :pending => :processing
48
+ end
49
+
50
+ event :error_dalliance do
51
+ transition :processing => :processing_error
52
+ end
53
+
54
+ event :finish_dalliance do
55
+ transition :processing => :completed
56
+ end
57
+ end
58
+ #END state_machine(s)
59
+ end
60
+
61
+ module ClassMethods
62
+ def dalliance_status_in_load_select_array
63
+ state_machine(:dalliance_status).states.map {|state| [state.human_name, state.name] }
64
+ end
65
+ end
66
+
67
+ #Force backgound_processing w/ true
68
+ def dalliance_background_process(backgound_processing = nil)
69
+ if backgound_processing || (backgound_processing.nil? && Dalliance.background_processing?)
70
+ delay.dalliance_process(true)
71
+ else
72
+ dalliance_process(false)
73
+ end
74
+ end
75
+
76
+ #backgound_processing == false will re-raise any exceptions
77
+ def dalliance_process(backgound_processing = false)
78
+ begin
79
+ start_dalliance!
80
+
81
+ build_dalliance_progress_meter(:total_count => calculate_dalliance_progress_meter_total_count).save!
82
+
83
+ self.send(self.class.dalliance_options[:dalliance_method])
84
+
85
+ finish_dalliance!
86
+ rescue StandardError => e
87
+ #Save the error for future analysis...
88
+ self.dalliance_error_hash = {:error => e, :message => e.message, :backtrace => e.backtrace}
89
+
90
+ error_dalliance!
91
+
92
+ #Don't raise the error if we're backgound_processing...
93
+ raise e unless backgound_processing
94
+ ensure
95
+ if dalliance_progress_meter
96
+ dalliance_progress_meter.destroy
97
+ end
98
+ end
99
+ end
100
+
101
+ def dalliance_progress
102
+ if completed?
103
+ 100
104
+ else
105
+ if dalliance_progress_meter
106
+ dalliance_progress_meter.progress
107
+ else
108
+ 0
109
+ end
110
+ end
111
+ end
112
+
113
+ #If the progress_meter_total_count_method is not implemented just use 1...
114
+ def calculate_dalliance_progress_meter_total_count
115
+ if respond_to?(self.class.dalliance_options[:dalliance_progress_meter_total_count_method])
116
+ self.send(self.class.dalliance_options[:dalliance_progress_meter_total_count_method])
117
+ else
118
+ 1
119
+ end
120
+ end
121
+ end
122
+
123
+ #http://yehudakatz.com/2009/11/12/better-ruby-idioms/
124
+ class ActiveRecord::Base
125
+ def self.dalliance(*args)
126
+ options = args.last.is_a?(Hash) ? Dalliance.options.merge(args.pop) : Dalliance.options
127
+
128
+ case args.length
129
+ when 1
130
+ options[:dalliance_method] = args[0]
131
+ else
132
+ raise ArgumentError, "Incorrect number of Arguements provided"
133
+ end
134
+
135
+ cattr_accessor :dalliance_options
136
+ self.dalliance_options = options
137
+ include Dalliance
138
+ end
139
+ end
@@ -0,0 +1,22 @@
1
+ require 'rails/generators/migration'
2
+ require 'rails/generators/active_record'
3
+
4
+ module Dalliance
5
+ class ProgressMeterGenerator < Rails::Generators::Base
6
+ include Rails::Generators::Migration
7
+
8
+ desc "Create a migration to add dalliance_progress_meters"
9
+
10
+ def self.source_root
11
+ @source_root ||= File.expand_path('../templates', __FILE__)
12
+ end
13
+
14
+ def self.next_migration_number(path)
15
+ ActiveRecord::Generators::Base.next_migration_number(path)
16
+ end
17
+
18
+ def generate_migration
19
+ migration_template 'migration.rb', 'db/migrate/create_dalliance_progress_meters'
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ class CreateDallianceProgressMeters < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :dalliance_progress_meters do |t|
4
+ t.belongs_to :dalliance_progress_model, :polymorphic => true
5
+
6
+ t.integer :current_count
7
+ t.integer :total_count
8
+ t.integer :progress
9
+
10
+ t.timestamps
11
+ end
12
+
13
+ add_index :dalliance_progress_meters, [:dalliance_progress_model_id, :dalliance_progress_model_type], :name => 'by_dalliance_progress_model'
14
+ end
15
+
16
+ def self.down
17
+ remove_index :dalliance_progress_meters, :name => 'by_dalliance_progress_model'
18
+
19
+ drop_table :dalliance_progress_meters
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ class <%= migration_class_name %> < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :<%= name.underscore.camelize.tableize %>, :dalliance_error_hash, :text
4
+ add_column :<%= name.underscore.camelize.tableize %>, :dalliance_status, :string, :null => false, :default => 'pending'
5
+ end
6
+
7
+ def self.down
8
+ remove_column :<%= name.underscore.camelize.tableize %>, :dalliance_error_hash
9
+ remove_column :<%= name.underscore.camelize.tableize %>, :dalliance_status
10
+ end
11
+ end
@@ -0,0 +1,33 @@
1
+ #Adapted from paperclip...
2
+ #https://github.com/thoughtbot/paperclip
3
+
4
+ require 'rails/generators/active_record'
5
+
6
+ module Dalliance
7
+ class UpdateGenerator < ActiveRecord::Generators::Base
8
+ desc "Create a migration to add dalliance-specific fields to your model. " +
9
+ "The NAME argument is the name of your model"
10
+
11
+ def self.source_root
12
+ @source_root ||= File.expand_path('../templates', __FILE__)
13
+ end
14
+
15
+ def generate_migration
16
+ migration_template "migration.rb.erb", "db/migrate/#{migration_file_name}"
17
+ end
18
+
19
+ protected
20
+
21
+ def migration_name
22
+ "add_dalliance_to_#{name.underscore}"
23
+ end
24
+
25
+ def migration_file_name
26
+ "#{migration_name}.rb"
27
+ end
28
+
29
+ def migration_class_name
30
+ migration_name.camelize
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ describe DallianceModel do
4
+ subject { DallianceModel.create }
5
+
6
+ before(:all) do
7
+ Dalliance.options[:background_processing] = true
8
+ end
9
+
10
+ context "success" do
11
+ before(:all) do
12
+ DallianceModel.dalliance_options[:dalliance_method] = :dalliance_success_method
13
+ end
14
+
15
+ it "should not call the dalliance_method w/o a Delayed::Worker" do
16
+ subject.dalliance_background_process
17
+ subject.reload
18
+
19
+ subject.should_not be_successful
20
+ Delayed::Job.count.should == 1
21
+ end
22
+
23
+ it "should call the dalliance_method w/ a Delayed::Worker" do
24
+ subject.dalliance_background_process
25
+ Delayed::Worker.new.work_off
26
+ subject.reload
27
+
28
+ subject.should be_successful
29
+ Delayed::Job.count.should == 0
30
+ end
31
+
32
+ it "should set the dalliance_status to completed" do
33
+ subject.dalliance_background_process
34
+ Delayed::Worker.new.work_off
35
+ subject.reload
36
+
37
+ subject.should be_completed
38
+ end
39
+
40
+ it "should set the dalliance_progress to 100" do
41
+ subject.dalliance_background_process
42
+ Delayed::Worker.new.work_off
43
+ subject.reload
44
+
45
+ subject.dalliance_progress.should == 100
46
+ end
47
+ end
48
+
49
+ context "raise error" do
50
+ before(:all) do
51
+ DallianceModel.dalliance_options[:dalliance_method] = :dalliance_error_method
52
+ end
53
+
54
+ it "should NOT raise an error" do
55
+ subject.dalliance_background_process
56
+
57
+ Delayed::Worker.new.work_off
58
+
59
+ Delayed::Job.count.should == 0
60
+ end
61
+
62
+ it "should store the error" do
63
+ subject.dalliance_background_process
64
+ Delayed::Worker.new.work_off
65
+ subject.reload
66
+
67
+ subject.dalliance_error_hash.should_not be_empty
68
+ subject.dalliance_error_hash[:error].should == RuntimeError.new
69
+ subject.dalliance_error_hash[:message].should == 'RuntimeError'
70
+ subject.dalliance_error_hash[:backtrace].should_not be_blank
71
+ end
72
+
73
+ it "should set the dalliance_status to processing_error" do
74
+ subject.dalliance_background_process
75
+ Delayed::Worker.new.work_off
76
+ subject.reload
77
+
78
+ subject.should be_processing_error
79
+ end
80
+
81
+ it "should set the dalliance_progress to 0" do
82
+ subject.dalliance_background_process
83
+ Delayed::Worker.new.work_off
84
+ subject.reload
85
+
86
+ subject.dalliance_progress.should == 0
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Dalliance' do
4
+ end
@@ -0,0 +1,58 @@
1
+ require 'spec_helper'
2
+
3
+ describe DallianceModel do
4
+ subject { DallianceModel.create }
5
+
6
+ before(:all) do
7
+ Dalliance.options[:background_processing] = false
8
+ end
9
+
10
+ context "success" do
11
+ before(:all) do
12
+ DallianceModel.dalliance_options[:dalliance_method] = :dalliance_success_method
13
+ end
14
+
15
+ it "should call the dalliance_method" do
16
+ lambda { subject.dalliance_background_process }.should change(subject, :successful).from(false).to(true)
17
+ end
18
+
19
+ it "should set the dalliance_status to completed" do
20
+ lambda { subject.dalliance_background_process }.should change(subject, :dalliance_status).from('pending').to('completed')
21
+ end
22
+
23
+ it "should set the dalliance_progress to 100" do
24
+ lambda { subject.dalliance_background_process }.should change(subject, :dalliance_progress).from(0).to(100)
25
+ end
26
+ end
27
+
28
+ context "raise error" do
29
+ before(:all) do
30
+ DallianceModel.dalliance_options[:dalliance_method] = :dalliance_error_method
31
+ end
32
+
33
+ it "should raise an error" do
34
+ expect { subject.dalliance_background_process }.to raise_error(RuntimeError)
35
+ end
36
+
37
+ it "should store the error" do
38
+ expect { subject.dalliance_background_process }.to raise_error(RuntimeError)
39
+
40
+ subject.dalliance_error_hash.should_not be_empty
41
+ subject.dalliance_error_hash[:error].should == RuntimeError.new
42
+ subject.dalliance_error_hash[:message].should == 'RuntimeError'
43
+ subject.dalliance_error_hash[:backtrace].should_not be_blank
44
+ end
45
+
46
+ it "should set the dalliance_status to processing_error" do
47
+ expect { subject.dalliance_background_process }.to raise_error(RuntimeError)
48
+
49
+ subject.should be_processing_error
50
+ end
51
+
52
+ it "should set the dalliance_progress to 0" do
53
+ expect { subject.dalliance_background_process }.to raise_error(RuntimeError)
54
+
55
+ subject.dalliance_progress.should == 0
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,30 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ #Automatically included in a rails app...
5
+ require 'active_support'
6
+ require 'state_machine'
7
+ require 'delayed_job'
8
+
9
+ #Required for testing...
10
+ require 'delayed_job_active_record'
11
+
12
+ require 'dalliance'
13
+
14
+ RSpec.configure do |config|
15
+ #http://blog.rubyhead.com/2010/04/27/database-during-tests/
16
+ config.before do
17
+ ActiveRecord::Base.connection.begin_db_transaction
18
+ ActiveRecord::Base.connection.increment_open_transactions
19
+ end
20
+
21
+ config.after do
22
+ if ActiveRecord::Base.connection.open_transactions != 0
23
+ ActiveRecord::Base.connection.rollback_db_transaction
24
+ ActiveRecord::Base.connection.decrement_open_transactions
25
+ end
26
+ end
27
+ end
28
+
29
+ #We don't need a full rails app to test...
30
+ require 'support/active_record'
@@ -0,0 +1,54 @@
1
+ #Adapted from delayed_job_active_record
2
+ #https://github.com/collectiveidea/delayed_job_active_record
3
+
4
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
5
+ ActiveRecord::Migration.verbose = false
6
+
7
+ ActiveRecord::Schema.define do
8
+ create_table :dalliance_progress_meters, :force => true do |t|
9
+ t.belongs_to :dalliance_progress_model, :polymorphic => true
10
+
11
+ t.integer :current_count
12
+ t.integer :total_count
13
+ t.integer :progress
14
+
15
+ t.timestamps
16
+ end
17
+
18
+ add_index :dalliance_progress_meters, [:dalliance_progress_model_id, :dalliance_progress_model_type], :name => 'by_dalliance_progress_model'
19
+
20
+ create_table :delayed_jobs, :force => true do |table|
21
+ table.integer :priority, :default => 0
22
+ table.integer :attempts, :default => 0
23
+ table.text :handler
24
+ table.text :last_error
25
+ table.datetime :run_at
26
+ table.datetime :locked_at
27
+ table.datetime :failed_at
28
+ table.string :locked_by
29
+ table.string :queue
30
+ table.timestamps
31
+ end
32
+
33
+ add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority'
34
+
35
+ create_table :dalliance_models, :force => true do |t|
36
+ t.text :dalliance_error_hash
37
+ t.string :dalliance_status, :string, :null => false, :default => 'pending'
38
+
39
+ t.boolean :successful, :default => false
40
+ end
41
+ end
42
+
43
+ # Purely useful for test cases...
44
+ class DallianceModel < ActiveRecord::Base
45
+ dalliance :dalliance_success_method
46
+
47
+ def dalliance_success_method
48
+ update_attribute(:successful, true)
49
+ end
50
+
51
+ def dalliance_error_method
52
+ raise RuntimeError
53
+ end
54
+ end
metadata ADDED
@@ -0,0 +1,147 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dalliance
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Eric Sullivan
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-10 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: &70098455466720 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 3.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70098455466720
25
+ - !ruby/object:Gem::Dependency
26
+ name: activesupport
27
+ requirement: &70098455466100 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 3.0.0
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70098455466100
36
+ - !ruby/object:Gem::Dependency
37
+ name: delayed_job
38
+ requirement: &70098455465500 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 2.0.0
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70098455465500
47
+ - !ruby/object:Gem::Dependency
48
+ name: state_machine
49
+ requirement: &70098455465020 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70098455465020
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: &70098455464440 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70098455464440
69
+ - !ruby/object:Gem::Dependency
70
+ name: delayed_job_active_record
71
+ requirement: &70098455463520 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70098455463520
80
+ - !ruby/object:Gem::Dependency
81
+ name: sqlite3
82
+ requirement: &70098455462940 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70098455462940
91
+ description: ! ' Opinionated background processing for ActiveRecord w/ delayed_job
92
+ & state_machine '
93
+ email:
94
+ - eric.sullivan@annkissam.com
95
+ executables: []
96
+ extensions: []
97
+ extra_rdoc_files: []
98
+ files:
99
+ - .gitignore
100
+ - .rspec
101
+ - Gemfile
102
+ - LICENSE
103
+ - README.rdoc
104
+ - Rakefile
105
+ - dalliance.gemspec
106
+ - lib/dalliance.rb
107
+ - lib/dalliance/progress_meter.rb
108
+ - lib/dalliance/version.rb
109
+ - lib/generators/dalliance/progress_meter/progress_meter_generator.rb
110
+ - lib/generators/dalliance/progress_meter/templates/migration.rb
111
+ - lib/generators/dalliance/update/templates/migration.rb.erb
112
+ - lib/generators/dalliance/update/update_generator.rb
113
+ - spec/dalliance/asynchronous_spec.rb
114
+ - spec/dalliance/dalliance_spec.rb
115
+ - spec/dalliance/synchronous_spec.rb
116
+ - spec/spec_helper.rb
117
+ - spec/support/active_record.rb
118
+ homepage: https://github.com/annkissam/dalliance
119
+ licenses: []
120
+ post_install_message:
121
+ rdoc_options: []
122
+ require_paths:
123
+ - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ none: false
126
+ requirements:
127
+ - - ! '>='
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ! '>='
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ requirements: []
137
+ rubyforge_project: dalliance
138
+ rubygems_version: 1.8.10
139
+ signing_key:
140
+ specification_version: 3
141
+ summary: dalliance 0.0.1
142
+ test_files:
143
+ - spec/dalliance/asynchronous_spec.rb
144
+ - spec/dalliance/dalliance_spec.rb
145
+ - spec/dalliance/synchronous_spec.rb
146
+ - spec/spec_helper.rb
147
+ - spec/support/active_record.rb