acts_as_async 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE CHANGED
@@ -1,20 +1,7 @@
1
- Copyright (c) Brendan Loudermilk
1
+ Copyright (c) 2011 Brendan Loudermilk
2
2
 
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10
4
 
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
13
6
 
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,3 +1,122 @@
1
- # Async Record!
1
+ # ActsAsAsync
2
2
 
3
- It's pretty cool
3
+ ActsAsAsync is an ActiveRecord extension that provides your models with
4
+ easy-to-use Resque helpers.
5
+
6
+
7
+ ## Installation
8
+
9
+ Installing ActsAsAsync is as simple as adding it to your Gemfile:
10
+
11
+ $ cat Gemfile
12
+ ...
13
+ gem "acts_as_async"
14
+ ...
15
+
16
+
17
+ ## Usage
18
+
19
+ ActsAsAsync aims to be as simple as possible to use. Including it in your model
20
+ is as easy as:
21
+
22
+ class Post < ActiveRecord::Base
23
+ acts_as_async
24
+ end
25
+
26
+ ### Basic usage
27
+
28
+ ActsAsAsync adds three instance methods to your model that you can use to async
29
+ any other instance method:
30
+
31
+ post = Post.create(:body => "Wow, acts_as_async is neat!")
32
+
33
+ # Self-destruct as soon as possible
34
+ post.async(:destroy)
35
+
36
+ # Self-destruct at this time tomorrow
37
+ post.async_at(Time.now + 1.day, :destroy)
38
+
39
+ # Self-destruct in 10 minutes
40
+ post.async_in(10.minutes, :destroy)
41
+
42
+ It also adds three identical class methods:
43
+
44
+ Post.async(:destroy_all)
45
+ Post.async_at(1.day.from_now, :destroy_all)
46
+ Post.async_in(10.minutes, :destroy_all)
47
+
48
+ ### Dynamic methods
49
+
50
+ In addition to the helper methods above, ActsAsAsync supports dynamic methods
51
+ for any existing method on your model. For example:
52
+
53
+ class Audiobook < ActiveRecord::Base
54
+ acts_as_async
55
+
56
+ def transcribe
57
+ # Some long-running logic here
58
+ end
59
+
60
+ def read!
61
+ # Computers like to read too!
62
+ end
63
+
64
+ def paint(color)
65
+ # I don't know why you'd paint a book...
66
+ end
67
+ end
68
+
69
+ book = Audiobook.first
70
+
71
+ # Transcribe the book as soon as possible
72
+ book.async_transcribe
73
+
74
+ # Read the book at this time tomorrow
75
+ book.async_read_at!(Time.now + 1.day)
76
+
77
+ # Paint the book blue in a couple years
78
+ book.async_paint_in(2.years, "blue")
79
+
80
+ ### Additional notes
81
+
82
+ * You can pass any number of additional arguments to async'd methods so long
83
+ as they can be serialized into JSON
84
+ * Adding acts_as_async to your Gemfile automatically loads both Resque and
85
+ Resque-scheduler's rake tasks. This means you can use both
86
+ `$ rake resque:work` and `$ rake resque:scheduler` right out of the box.
87
+ * By deafult, each model will add tasks to a queue named "default". You can
88
+ pass the `:queue` option to `acts_as_async` to specify a different queue.
89
+ * Dynamic methods support names with exclamation points but not question
90
+ marks. This was a design decision to discourage misuse of the question mark
91
+ in method names. If you absolutely must async a method with a question mark,
92
+ just use one of the `async :method` helpers.
93
+
94
+
95
+ ## Everything else...
96
+
97
+ ActsAsAsync is simply a thin layer on top of [Resque][resque] and
98
+ [Resque-scheduler][resque_scheduler]. To learn how to configure your redis
99
+ connection, run workers, view the web interface, and more visit their home
100
+ pages.
101
+
102
+ [resque]: https://github.com/defunkt/resque
103
+ [resque_scheduler]: https://github.com/bvandenbos/resque-scheduler
104
+
105
+
106
+ ## Compatibility
107
+
108
+ ActsAsAsync is tested against the same Rubies as Resque: Ruby 1.8.7, 1.9.2,
109
+ Rubinius 2.0, and JRuby.
110
+
111
+ **Adding better test coverage is top priority at the moment. Don't be shy, issue
112
+ a pull request with your tests.**
113
+
114
+ ![Build Status](https://secure.travis-ci.org/bloudermilk/acts_as_async.png?branch=master&.png)
115
+
116
+ [Build History](http://travis-ci.org/mongoid/mongoid)
117
+
118
+
119
+ ## License
120
+
121
+ ActsAsAsync is released under the MIT license. See the LICENSE file for more
122
+ info.
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require "bundler"
2
+ Bundler.setup
3
+
4
+ require "rake"
5
+ require "rspec"
6
+ require "rspec/core/rake_task"
7
+
8
+ lib_path = File.expand_path("../lib", __FILE__)
9
+ $LOAD_PATH.unshift lib_path unless $LOAD_PATH.include? lib_path
10
+
11
+ require "acts_as_async/version"
12
+
13
+ RSpec::Core::RakeTask.new("spec")
14
+ task :default => :spec
15
+
16
+ task :build do
17
+ system "gem build acts_as_async.gemspec"
18
+ end
19
+
20
+ task :install => :build do
21
+ system "sudo gem install acts_as_async-#{ActsAsAsync::VERSION}.gem"
22
+ end
23
+
@@ -4,12 +4,12 @@ module ActsAsAsync
4
4
 
5
5
  module ClassMethods
6
6
  def acts_as_async(opts={})
7
- # Make the default queue for this class "default"
8
- opts.reverse_merge!(queue: :default)
9
-
10
- # Set the queue unless one is already set
11
- unless instance_variable_defined?(:@queue)
7
+ # Set the queue to the passed option
8
+ if opts[:queue]
12
9
  instance_variable_set(:@queue, opts[:queue])
10
+ # If no option was passed and there isn't a queue defined, use "default"
11
+ elsif !instance_variable_defined?(:@queue)
12
+ instance_variable_set(:@queue, :default)
13
13
  end
14
14
 
15
15
  include ActsAsAsync::Helper
@@ -2,6 +2,11 @@ module ActsAsAsync
2
2
  module Helper
3
3
  extend ActiveSupport::Concern
4
4
 
5
+ included do
6
+ include SharedMethods
7
+ extend SharedMethods
8
+ end
9
+
5
10
  module ClassMethods
6
11
  # Args will be an optional ID, a method name and optional arguments
7
12
  def perform(*args)
@@ -17,7 +22,7 @@ module ActsAsAsync
17
22
  method = args.shift
18
23
  end
19
24
 
20
- receiver.send(method, *args)
25
+ receiver.__send__(method, *args)
21
26
  end
22
27
 
23
28
  def async(method, *args)
@@ -46,5 +51,47 @@ module ActsAsAsync
46
51
  Resque.enqueue_in(time, self.class, id, method, *args)
47
52
  end
48
53
  end
54
+
55
+ module SharedMethods
56
+ METHOD_REGEXP = /\Aasync_([a-zA-Z]\w*?)(_at|_in)?(!)?\z/
57
+
58
+ def method_missing(method_id, *args, &block)
59
+ if method_id =~ METHOD_REGEXP
60
+ # Compose the method to be async'd, with an optional bang
61
+ method = "#{$1}#{$3}"
62
+
63
+ if respond_to? method
64
+ # If we're not using the _at or _in methods, just call async
65
+ if $2.nil?
66
+ __send__(:async, method, *args)
67
+
68
+ # Otherwise compose the Helper method
69
+ else
70
+ __send__("async#{$2}", args.shift, method, *args)
71
+ end
72
+ else
73
+ message = "Tried to async the method #{method} but it isn't defined."
74
+ raise NoMethodError, message
75
+ end
76
+ else
77
+ super
78
+ end
79
+ end
80
+
81
+ # Use respond_to_missing? on newer Ruby versions but fall back to
82
+ # overriding respond_to? on older versions. In both cases, return
83
+ # true for any match, even if the method to be async'd doesn't
84
+ # exist, since technically we do respond to that method but throw
85
+ # an exception.
86
+ if RUBY_VERSION >= "1.9.2"
87
+ def respond_to_missing?(method_id, *)
88
+ method_id =~ METHOD_REGEXP || super
89
+ end
90
+ else
91
+ def respond_to?(method_id, *)
92
+ method_id =~ METHOD_REGEXP || super
93
+ end
94
+ end
95
+ end
49
96
  end
50
97
  end
@@ -1,3 +1,3 @@
1
1
  module ActsAsAsync
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/acts_as_async.rb CHANGED
@@ -1,3 +1,7 @@
1
+ require "active_support/concern"
2
+
3
+ require "active_record"
4
+
1
5
  require "resque"
2
6
  require "resque_scheduler"
3
7
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_async
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-21 00:00:00.000000000Z
12
+ date: 2011-10-27 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: resque
16
- requirement: &70318317253520 !ruby/object:Gem::Requirement
16
+ requirement: &70184556181300 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70318317253520
24
+ version_requirements: *70184556181300
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: resque-scheduler
27
- requirement: &70318317253100 !ruby/object:Gem::Requirement
27
+ requirement: &70184556180800 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,21 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70318317253100
35
+ version_requirements: *70184556180800
36
+ - !ruby/object:Gem::Dependency
37
+ name: activesupport
38
+ requirement: &70184556180220 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70184556180220
36
47
  - !ruby/object:Gem::Dependency
37
48
  name: activerecord
38
- requirement: &70318317252680 !ruby/object:Gem::Requirement
49
+ requirement: &70184556179620 !ruby/object:Gem::Requirement
39
50
  none: false
40
51
  requirements:
41
52
  - - ! '>='
@@ -43,29 +54,27 @@ dependencies:
43
54
  version: '0'
44
55
  type: :runtime
45
56
  prerelease: false
46
- version_requirements: *70318317252680
47
- description: ! ' This gem is so crazy you won''t believe.
48
-
49
- '
50
- email: brendan@gophilosophie.com
57
+ version_requirements: *70184556179620
58
+ description: ActsAsAsync is an ActiveRecord extension that provides your models with
59
+ easy-to-use Resque helpers.
60
+ email:
61
+ - brendan@gophilosophie.com
51
62
  executables: []
52
63
  extensions: []
53
- extra_rdoc_files:
54
- - LICENSE
55
- - README.md
64
+ extra_rdoc_files: []
56
65
  files:
57
- - README.md
58
- - LICENSE
59
66
  - lib/acts_as_async/base_extensions.rb
60
67
  - lib/acts_as_async/helper.rb
61
68
  - lib/acts_as_async/railtie.rb
62
69
  - lib/acts_as_async/version.rb
63
70
  - lib/acts_as_async.rb
71
+ - LICENSE
72
+ - Rakefile
73
+ - README.md
64
74
  homepage: http://github.com/bloudermilk/acts_as_async
65
75
  licenses: []
66
76
  post_install_message:
67
- rdoc_options:
68
- - --charset=UTF-8
77
+ rdoc_options: []
69
78
  require_paths:
70
79
  - lib
71
80
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -74,16 +83,22 @@ required_ruby_version: !ruby/object:Gem::Requirement
74
83
  - - ! '>='
75
84
  - !ruby/object:Gem::Version
76
85
  version: '0'
86
+ segments:
87
+ - 0
88
+ hash: -4440450066479930508
77
89
  required_rubygems_version: !ruby/object:Gem::Requirement
78
90
  none: false
79
91
  requirements:
80
92
  - - ! '>='
81
93
  - !ruby/object:Gem::Version
82
94
  version: '0'
95
+ segments:
96
+ - 0
97
+ hash: -4440450066479930508
83
98
  requirements: []
84
99
  rubyforge_project:
85
100
  rubygems_version: 1.8.10
86
101
  signing_key:
87
102
  specification_version: 3
88
- summary: Acts As Async is a Resque-backed ActiveRecord delayed job tool
103
+ summary: The marriage of ActiveRecord and Resque.
89
104
  test_files: []