resque-async_deliver 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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