Skip to content
This repository has been archived by the owner on Apr 8, 2019. It is now read-only.

Commit

Permalink
initial import
Browse files Browse the repository at this point in the history
  • Loading branch information
nragaz committed Jun 14, 2011
0 parents commit 890a4f5
Show file tree
Hide file tree
Showing 54 changed files with 991 additions and 0 deletions.
13 changes: 13 additions & 0 deletions Gemfile
@@ -0,0 +1,13 @@
source "http://rubygems.org"

gemspec

gem 'rails', '3.1.0.rc4'
gem 'resque'

# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'

if RUBY_VERSION < '1.9'
gem "ruby-debug", ">= 0.10.3"
end
112 changes: 112 additions & 0 deletions Gemfile.lock
@@ -0,0 +1,112 @@
PATH
remote: .
specs:
resque-async-method (0.0.1)
activesupport
resque

GEM
remote: http://rubygems.org/
specs:
actionmailer (3.1.0.rc4)
actionpack (= 3.1.0.rc4)
mail (~> 2.3.0)
actionpack (3.1.0.rc4)
activemodel (= 3.1.0.rc4)
activesupport (= 3.1.0.rc4)
builder (~> 3.0.0)
erubis (~> 2.7.0)
i18n (~> 0.6)
rack (~> 1.3.0)
rack-cache (~> 1.0.1)
rack-mount (~> 0.8.1)
rack-test (~> 0.6.0)
sprockets (~> 2.0.0.beta.10)
tzinfo (~> 0.3.27)
activemodel (3.1.0.rc4)
activesupport (= 3.1.0.rc4)
bcrypt-ruby (~> 2.1.4)
builder (~> 3.0.0)
i18n (~> 0.6)
activerecord (3.1.0.rc4)
activemodel (= 3.1.0.rc4)
activesupport (= 3.1.0.rc4)
arel (~> 2.1.1)
tzinfo (~> 0.3.27)
activeresource (3.1.0.rc4)
activemodel (= 3.1.0.rc4)
activesupport (= 3.1.0.rc4)
activesupport (3.1.0.rc4)
multi_json (~> 1.0)
arel (2.1.1)
bcrypt-ruby (2.1.4)
builder (3.0.0)
erubis (2.7.0)
hike (1.0.0)
i18n (0.6.0)
json (1.5.1)
mail (2.3.0)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
mime-types (1.16)
multi_json (1.0.3)
polyglot (0.3.1)
rack (1.3.0)
rack-cache (1.0.2)
rack (>= 0.4)
rack-mount (0.8.1)
rack (>= 1.0.0)
rack-ssl (1.3.2)
rack
rack-test (0.6.0)
rack (>= 1.0)
rails (3.1.0.rc4)
actionmailer (= 3.1.0.rc4)
actionpack (= 3.1.0.rc4)
activerecord (= 3.1.0.rc4)
activeresource (= 3.1.0.rc4)
activesupport (= 3.1.0.rc4)
bundler (~> 1.0)
railties (= 3.1.0.rc4)
railties (3.1.0.rc4)
actionpack (= 3.1.0.rc4)
activesupport (= 3.1.0.rc4)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (~> 0.14.6)
rake (0.9.2)
rdoc (3.6.1)
redis (2.2.1)
redis-namespace (1.0.3)
redis (< 3.0.0)
resque (1.17.1)
json (>= 1.4.6, < 1.6)
redis-namespace (~> 1.0.2)
sinatra (>= 0.9.2)
vegas (~> 0.1.2)
sinatra (1.2.6)
rack (~> 1.1)
tilt (>= 1.2.2, < 2.0)
sprockets (2.0.0.beta.10)
hike (~> 1.0)
rack (~> 1.0)
tilt (!= 1.3.0, ~> 1.1)
sqlite3 (1.3.3)
thor (0.14.6)
tilt (1.3.2)
treetop (1.4.9)
polyglot (>= 0.3.1)
tzinfo (0.3.28)
vegas (0.1.8)
rack (>= 1.0.0)

PLATFORMS
ruby

DEPENDENCIES
rails (= 3.1.0.rc4)
resque
resque-async-method!
sqlite3
20 changes: 20 additions & 0 deletions MIT-LICENSE
@@ -0,0 +1,20 @@
Copyright 2011 Nick Ragaz

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:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

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.
48 changes: 48 additions & 0 deletions README.md
@@ -0,0 +1,48 @@
Resque::Plugins::Async::Method
==============================

Make Active Record instance methods asynchronous using [resque](http://www.github.com/defunkt/resque).

Usage
-----

class User < ActiveRecord::Base
# Not needed! This is done using a hook on ActiveRecord::Base.
# include Resque::Plugins::Async::Method
def preprocess_avatar_for_a_long_time
# do stuff
end
async_method :preprocess_avatar_for_a_long_time
def send_a_very_long_email
# do stuff
end
async_method :send_a_very_long_email, queue: 'emails'
end

u = User.find(1)

u.preprocess_avatar_for_a_long_time # => queued in 'users' queue
u.send_a_very_long_email # => queued in 'emails' queue
u.sync_send_a_very_long_email # => happens right away!

Note that in the test environment, none of this magic happens. You can test the expected output immediately.

Method return values will change. `Resque.enqueue` will return `[]` from an async'ed method.

Sometimes it's nice to async a method that you're including from a module:

module MyExtension
extend ActiveSupport::Concern
include Resque::Plugins::Async::Method
included do
async_method :generate_matrix, queue: 'matrices'
end
def generate_matrix
# do stuff
end
end
34 changes: 34 additions & 0 deletions Rakefile
@@ -0,0 +1,34 @@
#!/usr/bin/env rake
begin
require 'bundler/setup'
rescue LoadError
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
end
begin
require 'rdoc/task'
rescue LoadError
require 'rdoc/rdoc'
require 'rake/rdoctask'
RDoc::Task = Rake::RDocTask
end

RDoc::Task.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'Resque::Plugins::Async::Method'
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.rdoc_files.include('README.rdoc')
rdoc.rdoc_files.include('lib/**/*.rb')
end


require 'rake/testtask'

Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.verbose = false
end


task :default => :test
14 changes: 14 additions & 0 deletions lib/resque-async-method.rb
@@ -0,0 +1,14 @@
require 'active_support/dependencies'

module Resque
module Plugins
module Async
autoload :Method, 'resque/plugins/async/method'
autoload :Worker, 'resque/plugins/async/worker'
end
end
end

ActiveSupport.on_load(:active_record) do
include Resque::Plugins::Async::Method
end
29 changes: 29 additions & 0 deletions lib/resque/plugins/async/method.rb
@@ -0,0 +1,29 @@
require 'resque/plugins/async/worker'

module Resque::Plugins::Async::Method
extend ActiveSupport::Concern

module ClassMethods
def async_method(method_name, opts={})
# Allow tests to call sync_ methods ...
alias_method :"sync_#{method_name}", method_name

# ... but don't actually make them asynchronous
return if Rails.env.test?

define_method "#{method_name}" do |*args|
my_klass = Resque::Plugins::Async::Worker
my_klass.queue = opts[:queue] ||
send(:class).name.underscore.pluralize

Resque.enqueue(
my_klass,
send(:class).name,
send(:id),
:"sync_#{method_name}",
*args
)
end
end
end
end
15 changes: 15 additions & 0 deletions lib/resque/plugins/async/worker.rb
@@ -0,0 +1,15 @@
class Resque::Plugins::Async::Worker
@queue = :async_methods

def self.queue=(name)
@queue = name
end

def self.queue
@queue
end

def self.perform(klass, *args)
klass.constantize.find(args.shift).send(args.shift, *args)
end
end
15 changes: 15 additions & 0 deletions resque-async-method.gemspec
@@ -0,0 +1,15 @@
Gem::Specification.new do |s|
s.name = "resque-async-method"
s.summary = "Make Active Record instance methods asynchronous using resque."
s.description = "Make Active Record instance methods asynchronous using resque."
s.files = Dir["lib/**/*"] + ["MIT-LICENSE", "Rakefile", "README.rdoc"]
s.version = "0.0.1"
s.authors = ["Nick Ragaz"]
s.email = "nick.ragaz@gmail.com"
s.homepage = "http://github.com/nragaz/resque-async-method"

s.add_dependency 'resque'
s.add_dependency 'activesupport'

s.add_development_dependency 'sqlite3'
end
18 changes: 18 additions & 0 deletions test/async_method_test.rb
@@ -0,0 +1,18 @@
require 'test_helper'

class AsyncMethodTest < ActiveSupport::TestCase
test "define methods" do
assert User.new.respond_to?(:long_method)
assert User.new.respond_to?(:another_long_method)

assert User.new.respond_to?(:sync_long_method)
assert User.new.respond_to?(:sync_another_long_method)
end

test "enqueue jobs" do
user = User.first

assert_equal [], user.long_method
assert_equal 'success!', user.sync_long_method
end
end
7 changes: 7 additions & 0 deletions test/dummy/Rakefile
@@ -0,0 +1,7 @@
#!/usr/bin/env rake
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.

require File.expand_path('../config/application', __FILE__)

Dummy::Application.load_tasks
9 changes: 9 additions & 0 deletions test/dummy/app/assets/javascripts/application.js
@@ -0,0 +1,9 @@
// This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
//= require jquery
//= require jquery_ujs
//= require_tree .
7 changes: 7 additions & 0 deletions test/dummy/app/assets/stylesheets/application.css
@@ -0,0 +1,7 @@
/*
* This is a manifest file that'll automatically include all the stylesheets available in this directory
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
* the top of the compiled file, but it's generally better to create a new file per style scope.
*= require_self
*= require_tree .
*/
3 changes: 3 additions & 0 deletions test/dummy/app/controllers/application_controller.rb
@@ -0,0 +1,3 @@
class ApplicationController < ActionController::Base
protect_from_forgery
end
2 changes: 2 additions & 0 deletions test/dummy/app/helpers/application_helper.rb
@@ -0,0 +1,2 @@
module ApplicationHelper
end
Empty file added test/dummy/app/mailers/.gitkeep
Empty file.
Empty file added test/dummy/app/models/.gitkeep
Empty file.
15 changes: 15 additions & 0 deletions test/dummy/app/models/user.rb
@@ -0,0 +1,15 @@
class User < ActiveRecord::Base
def long_method
sleep 2

return "success!"
end
async_method :long_method, queue: 'long-methods'

def another_long_method
sleep 2

return "success!"
end
async_method :another_long_method
end
14 changes: 14 additions & 0 deletions test/dummy/app/views/layouts/application.html.erb
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Dummy</title>
<%= stylesheet_link_tag "application" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
<body>

<%= yield %>

</body>
</html>

0 comments on commit 890a4f5

Please sign in to comment.