resque-async_deliver 1.0.0

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.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.2@resque-async_deliver --create
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # resque-async\_deliver
2
+
3
+ resque-async\_deliver is a simple gem to send emails asynchronously
4
+ using [Resque](https://github.com/defunkt/resque) without having to
5
+ change much in your existing codebase.
6
+
7
+ ## Installing
8
+
9
+ In your Gemfile:
10
+
11
+ ```ruby
12
+ gem 'resque-async_deliver'
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ Whenever you want to asynchronously send an email, simply change
18
+
19
+ ```ruby
20
+ SomeMailer.some_mail(an_argument, another_argument).deliver
21
+ ```
22
+
23
+ to this
24
+
25
+ ```ruby
26
+ SomeMailer.async_deliver.some_mail(an_argument, another_argument)
27
+ ```
28
+
29
+ This will enqueue a job that will simply run
30
+
31
+ ```ruby
32
+ SomeMailer.some_mail(an_argument, another_argument).deliver
33
+ ```
34
+
35
+ You don't have to change your mailers, even if they take ActiveRecord
36
+ objects as arguments. Since all the arguments will be JSON encoded
37
+ by Resque before storing them in Redis, ActiveRecord objects will be
38
+ serialized as a hash containing the class and the id of the model.
39
+ resque-async\_deliver will then `find` the records and pass them to the
40
+ mailer.
41
+
42
+ ## Details
43
+
44
+ Tested on ruby 1.8.7 and 1.9.2.
45
+
46
+ ## Contributing
47
+
48
+ 1. Fork
49
+ 2. Create a topic branch
50
+ 3. Push to your branch
51
+ 4. Send a pull request
52
+
53
+ ## Author
54
+
55
+ Philipe Fatio
56
+ <philipe.fatio@gmail.com>
57
+ [@fphilipe](http://twitter.com/fphilipe)
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
@@ -0,0 +1,15 @@
1
+ # coding: UTF-8
2
+
3
+ require 'action_mailer'
4
+
5
+ module Resque::AsyncDeliver
6
+ module ActionMailerExtension
7
+ def async_deliver
8
+ Proxy.new(self)
9
+ end
10
+ end
11
+
12
+ def self.initialize
13
+ ActionMailer::Base.send(:extend, ActionMailerExtension)
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ # coding: UTF-8
2
+
3
+ module Resque::AsyncDeliver
4
+ class MailJob
5
+ @queue = :mail
6
+
7
+ def self.perform(*args)
8
+ mailer = args.shift.constantize
9
+ method_name = args.shift
10
+ arguments = []
11
+ args.each do |a|
12
+ if a.is_a? Hash and
13
+ klass = a['async_deliver_class'] || a[:async_deliver_class] and
14
+ id = a['async_deliver_id'] || a[:async_deliver_id]
15
+ arguments << klass.constantize.find(id)
16
+ else
17
+ arguments << a
18
+ end
19
+ end
20
+ mailer.__send__(method_name, *arguments).deliver
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ # coding: UTF-8
2
+
3
+ module Resque::AsyncDeliver
4
+ class Proxy
5
+ def initialize(klass)
6
+ @klass = klass.name
7
+ end
8
+
9
+ def method_missing(method, *args)
10
+ arguments = [ @klass, method ]
11
+ args.each do |a|
12
+ if a.class < ::ActiveRecord::Base
13
+ arguments << { :async_deliver_class => a.class.to_s, :async_deliver_id => a.id }
14
+ else
15
+ arguments << a
16
+ end
17
+ end
18
+ Resque.enqueue(MailJob, *arguments)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ # coding: UTF-8
2
+
3
+ require 'rails'
4
+
5
+ module Resque::AsyncDeliver
6
+ class Railtie < Rails::Railtie
7
+ initializer :after_initialize do
8
+ ActiveSupport.on_load(:action_mailer) do
9
+ Resque::AsyncDeliver.initialize
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ module Resque
2
+ module AsyncDeliver
3
+ VERSION = '1.0.0'
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ # coding: UTF-8
2
+
3
+ require 'resque'
4
+ require 'async_deliver/mail_job'
5
+ require 'async_deliver/proxy'
6
+ require 'async_deliver/action_mailer_extension'
7
+
8
+ if defined? Rails
9
+ require 'async_deliver/railtie'
10
+ else
11
+ Resque::AsyncDeliver.initialize
12
+ end
@@ -0,0 +1,34 @@
1
+ # coding: UTF-8
2
+
3
+ $:.push File.expand_path("../lib", __FILE__)
4
+ require "async_deliver/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "resque-async_deliver"
8
+ s.version = Resque::AsyncDeliver::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ["Philipe Fatio"]
11
+ s.email = ["philipe.fatio@gmail.com"]
12
+ s.homepage = "https://github.com/fphilipe/resque-deliver_asynchronously"
13
+ s.summary = %q{Deliver mails asynchronously using Resque without explicitly creating a performable job.}
14
+ s.description = <<-description
15
+ This gem makes it possible to send mails asynchronously using Resque by
16
+ simply rewriting `SomeMailer.some_mail(ar_resource, 1234).deliver` to
17
+ `SomeMailer.async_deliver.some_mail(ar_resource, 1234)`. Using ActiveRecord
18
+ objects as arguments to mailers is still possible. This is achieved by storing
19
+ the class name and the record id as arguments in the Resque queue which will be
20
+ transformed back to records by the mailer job and passed along to the mailer.
21
+ description
22
+
23
+ s.files = `git ls-files`.split("\n")
24
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
25
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
26
+ s.require_paths = ["lib"]
27
+
28
+ s.add_dependency 'resque' , '~> 1.0'
29
+ s.add_dependency 'actionmailer', '~> 3.0'
30
+
31
+ s.add_development_dependency 'rspec-core'
32
+ s.add_development_dependency 'rspec-expectations'
33
+ s.add_development_dependency 'mocha'
34
+ end
@@ -0,0 +1,15 @@
1
+ # coding: UTF-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'a class extended with Resque::AsyncDeliver::ActionMailerExtension' do
6
+ describe '.async_deliver' do
7
+ before do
8
+ Resque::AsyncDeliver::Proxy.expects(:new).with(TestMailer)
9
+ end
10
+
11
+ it 'should return a Proxy for the class' do
12
+ TestMailer.async_deliver
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ # coding: UTF-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'requiring resque-async_deliver' do
6
+ it 'should extend ActionMailer with Resque::AsyncDeliver::ActionMailerExtension' do
7
+ ActionMailer::Base.should respond_to :async_deliver
8
+ end
9
+ end
@@ -0,0 +1,38 @@
1
+ # coding: UTF-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Resque::AsyncDeliver::MailJob do
6
+ describe '.perform' do
7
+ let(:user) { TestUser.instance }
8
+ let(:resource) { TestResource.instance }
9
+
10
+ before do
11
+ message = mock()
12
+ message.expects(:deliver)
13
+
14
+ TestMailer.expects(:test_message).with(
15
+ user,
16
+ 123,
17
+ "a string",
18
+ %q[ an array ],
19
+ { :a => 'hash' },
20
+ resource
21
+ ).returns(message)
22
+ end
23
+
24
+ it 'should instantiate a mail and deliver it' do
25
+ Resque::AsyncDeliver::MailJob.perform(
26
+ 'TestMailer',
27
+ :test_message,
28
+ { :async_deliver_class => 'TestUser',
29
+ :async_deliver_id => user.id },
30
+ 123,
31
+ "a string",
32
+ %q[ an array ],
33
+ { :a => 'hash' },
34
+ { :async_deliver_class => 'TestResource',
35
+ :async_deliver_id => resource.id })
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ # coding: UTF-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Resque::AsyncDeliver::Proxy do
6
+ describe '#method_missing' do
7
+ let(:proxy) { Resque::AsyncDeliver::Proxy.new(TestMailer) }
8
+ let(:user) { TestUser.instance }
9
+ let(:resource) { TestResource.instance }
10
+
11
+ before do
12
+ Resque.expects(:enqueue).with(
13
+ Resque::AsyncDeliver::MailJob,
14
+ 'TestMailer',
15
+ :test_message,
16
+ { :async_deliver_class => 'TestUser',
17
+ :async_deliver_id => user.id },
18
+ 123,
19
+ "a string",
20
+ %q[ an array ],
21
+ { :a => 'hash' },
22
+ { :async_deliver_class => 'TestResource',
23
+ :async_deliver_id => resource.id }
24
+ )
25
+ end
26
+
27
+ it 'should enqueue a MailJob in Resque' do
28
+ proxy.test_message(
29
+ user,
30
+ 123,
31
+ "a string",
32
+ %q[ an array ],
33
+ { :a => 'hash' },
34
+ resource
35
+ )
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,7 @@
1
+ # coding: UTF-8
2
+
3
+ require 'support'
4
+
5
+ RSpec.configure do |config|
6
+ config.mock_with :mocha
7
+ end
data/spec/support.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'resque'
2
+ require 'resque-async_deliver'
3
+ require 'action_mailer'
4
+ require 'singleton'
5
+
6
+ module ActiveRecord
7
+ class Base
8
+ include Singleton
9
+ def self.find(id); instance; end
10
+ end
11
+ end
12
+
13
+ class TestUser < ActiveRecord::Base
14
+ def id; 123; end
15
+ end
16
+
17
+ class TestResource < ActiveRecord::Base
18
+ def id; 456; end
19
+ end
20
+
21
+ class TestMailer < ActionMailer::Base
22
+ extend Resque::AsyncDeliver::ActionMailerExtension
23
+ def test_message; end
24
+ end
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: resque-async_deliver
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 1.0.0
6
+ platform: ruby
7
+ authors:
8
+ - Philipe Fatio
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-07-06 00:00:00 +02:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: resque
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ~>
23
+ - !ruby/object:Gem::Version
24
+ version: "1.0"
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: actionmailer
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: "3.0"
36
+ type: :runtime
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: rspec-core
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: rspec-expectations
51
+ prerelease: false
52
+ requirement: &id004 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ type: :development
59
+ version_requirements: *id004
60
+ - !ruby/object:Gem::Dependency
61
+ name: mocha
62
+ prerelease: false
63
+ requirement: &id005 !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ type: :development
70
+ version_requirements: *id005
71
+ description: |
72
+ This gem makes it possible to send mails asynchronously using Resque by
73
+ simply rewriting `SomeMailer.some_mail(ar_resource, 1234).deliver` to
74
+ `SomeMailer.async_deliver.some_mail(ar_resource, 1234)`. Using ActiveRecord
75
+ objects as arguments to mailers is still possible. This is achieved by storing
76
+ the class name and the record id as arguments in the Resque queue which will be
77
+ transformed back to records by the mailer job and passed along to the mailer.
78
+
79
+ email:
80
+ - philipe.fatio@gmail.com
81
+ executables: []
82
+
83
+ extensions: []
84
+
85
+ extra_rdoc_files: []
86
+
87
+ files:
88
+ - .gitignore
89
+ - .rspec
90
+ - .rvmrc
91
+ - Gemfile
92
+ - README.md
93
+ - Rakefile
94
+ - lib/async_deliver/action_mailer_extension.rb
95
+ - lib/async_deliver/mail_job.rb
96
+ - lib/async_deliver/proxy.rb
97
+ - lib/async_deliver/railtie.rb
98
+ - lib/async_deliver/version.rb
99
+ - lib/resque-async_deliver.rb
100
+ - resque-async_deliver.gemspec
101
+ - spec/async_deliver/action_mailer_extension_spec.rb
102
+ - spec/async_deliver/async_deliver_spec.rb
103
+ - spec/async_deliver/mail_job_spec.rb
104
+ - spec/async_deliver/proxy_spec.rb
105
+ - spec/spec_helper.rb
106
+ - spec/support.rb
107
+ has_rdoc: true
108
+ homepage: https://github.com/fphilipe/resque-deliver_asynchronously
109
+ licenses: []
110
+
111
+ post_install_message:
112
+ rdoc_options: []
113
+
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: "0"
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: "0"
128
+ requirements: []
129
+
130
+ rubyforge_project:
131
+ rubygems_version: 1.6.2
132
+ signing_key:
133
+ specification_version: 3
134
+ summary: Deliver mails asynchronously using Resque without explicitly creating a performable job.
135
+ test_files:
136
+ - spec/async_deliver/action_mailer_extension_spec.rb
137
+ - spec/async_deliver/async_deliver_spec.rb
138
+ - spec/async_deliver/mail_job_spec.rb
139
+ - spec/async_deliver/proxy_spec.rb
140
+ - spec/spec_helper.rb
141
+ - spec/support.rb