farm 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ Farm
2
+ ====
3
+
4
+ "Farm out" background jobs by running them immediately as a one-off Heroku process. Only works with Rails >= 3.0.
5
+
6
+ Install:
7
+
8
+ gem install farm
9
+
10
+ Set the environment variables `API_KEY` and `APP_NAME`.
11
+
12
+ Call with the farm method:
13
+
14
+ Foo.bar #=> Run directly
15
+ Foo.farm.bar #=> Run in background as one-off Heroku process.
@@ -0,0 +1,7 @@
1
+ require 'active_support'
2
+ require 'farm/message_sending'
3
+ require 'farm/performable_method'
4
+ require 'farm/railtie' if defined?(Rails)
5
+
6
+ Object.send(:include, Farm::MessageSending)
7
+ Module.send(:include, Farm::MessageSending::ClassMethods)
@@ -0,0 +1,16 @@
1
+ require 'rest_client'
2
+
3
+ module Farm
4
+ class Http
5
+ def self.heroku_run(cmd)
6
+ endpoint = RestClient::Resource.new "https://api.heroku.com/apps/#{ENV['APP_NAME']}/ps",
7
+ '', ENV['API_KEY']
8
+ endpoint.post :command => cmd, :accept => 'application/json'
9
+ end
10
+ end
11
+ end
12
+
13
+ # curl -H "Accept: application/json" \
14
+ # -u :4e358ef46173ceeaf4ca6bcac86c948a27a9eb02 \
15
+ # -d "command=cmd" \
16
+ # -X POST https://api.heroku.com/apps/appname/ps
@@ -0,0 +1,44 @@
1
+ require 'active_support/basic_object'
2
+ require 'active_support/core_ext/module/aliasing'
3
+ require 'farm/runner'
4
+
5
+ module Farm
6
+ class FarmProxy < ActiveSupport::BasicObject
7
+ def initialize(payload_class, target, options)
8
+ @payload_class = payload_class
9
+ @target = target
10
+ @options = options
11
+ end
12
+
13
+ def method_missing(method, *args)
14
+ Runner.run({:payload_object => @payload_class.new(@target, method.to_sym, args)}.merge(@options))
15
+ end
16
+ end
17
+
18
+ module MessageSending
19
+ def farm(options = {})
20
+ FarmProxy.new(PerformableMethod, self, options)
21
+ end
22
+
23
+ module ClassMethods
24
+ def handle_asynchronously(method, opts = {})
25
+ aliased_method, punctuation = method.to_s.sub(/([?!=])$/, ''), $1
26
+ with_method, without_method = "#{aliased_method}_with_farm#{punctuation}", "#{aliased_method}_without_farm#{punctuation}"
27
+ define_method(with_method) do |*args|
28
+ curr_opts = opts.clone
29
+ curr_opts.each_key do |key|
30
+ if (val = curr_opts[key]).is_a?(Proc)
31
+ curr_opts[key] = if val.arity == 1
32
+ val.call(self)
33
+ else
34
+ val.call
35
+ end
36
+ end
37
+ end
38
+ farm(curr_opts).__send__(without_method, *args)
39
+ end
40
+ alias_method_chain method, :farm
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,33 @@
1
+ require 'active_support/core_ext/module/delegation'
2
+
3
+ module Farm
4
+ class PerformableMethod
5
+ attr_accessor :object, :method_name, :args
6
+
7
+ delegate :method, :to => :object
8
+
9
+ def initialize(object, method_name, args)
10
+ raise NoMethodError, "undefined method `#{method_name}' for #{object.inspect}" unless object.respond_to?(method_name, true)
11
+
12
+ self.object = object
13
+ self.args = args
14
+ self.method_name = method_name.to_sym
15
+ end
16
+
17
+ def display_name
18
+ "#{object.class}##{method_name}"
19
+ end
20
+
21
+ def perform
22
+ object.send(method_name, *args) if object
23
+ end
24
+
25
+ def method_missing(symbol, *args)
26
+ object.send(symbol, *args)
27
+ end
28
+
29
+ def respond_to?(symbol, include_private=false)
30
+ super || object.respond_to?(symbol, include_private)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,10 @@
1
+ require 'farm'
2
+ require 'rails'
3
+
4
+ module Farm
5
+ class Railtie < Rails::Railtie
6
+ rake_tasks do
7
+ load 'farm/tasks.rb'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,17 @@
1
+ require 'cgi'
2
+ require 'farm/http'
3
+ require 'yaml'
4
+
5
+ module Farm
6
+ class Runner
7
+ def self.run(*args)
8
+ @payload_object ||= args.shift[:payload_object]
9
+
10
+ unless @payload_object.respond_to?(:perform)
11
+ raise ArgumentError, 'Cannot run items which do not respond to perform'
12
+ end
13
+
14
+ Farm::Http.heroku_run "rake farm:run CMD='#{CGI.escape(YAML.dump(@payload_object))}'"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ require 'cgi'
2
+ require 'yaml'
3
+
4
+ namespace :farm do
5
+ desc "Farm out a method call."
6
+ task :run => :environment do
7
+ puts YAML.load(CGI.unescape(ENV['CMD'])).perform
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module Farm
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: farm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Matt Manning
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-23 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: &70178256971860 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70178256971860
25
+ - !ruby/object:Gem::Dependency
26
+ name: rake
27
+ requirement: &70178256971420 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70178256971420
36
+ - !ruby/object:Gem::Dependency
37
+ name: rest-client
38
+ requirement: &70178256970840 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 1.6.7
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70178256970840
47
+ description: Run background jobs as one-off Heroku processes.
48
+ email: matt.manning@gmail.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - README.md
54
+ - lib/farm.rb
55
+ - lib/farm/http.rb
56
+ - lib/farm/message_sending.rb
57
+ - lib/farm/performable_method.rb
58
+ - lib/farm/railtie.rb
59
+ - lib/farm/runner.rb
60
+ - lib/farm/tasks.rb
61
+ - lib/farm/version.rb
62
+ homepage: https://github.com/mattmanning/farm
63
+ licenses: []
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ requirements: []
81
+ rubyforge_project:
82
+ rubygems_version: 1.8.10
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: Run background jobs as one-off Heroku processes.
86
+ test_files: []