farm 0.0.1

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.
@@ -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: []