postpone 0.1.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.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,5 @@
1
+ --color
2
+ -fs
3
+ -Ilib
4
+ -Ispec
5
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in postpone.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Linus Oleander
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,97 @@
1
+ # Postpone
2
+
3
+ A [Beanstalkd](http://kr.github.com/beanstalkd/) backed asynchronous priority queue.
4
+
5
+ ## Why beanstalkd?
6
+
7
+ In contrast to other asynchronous priority queues Beanstalkd doesn't use polling behind the scene.
8
+ This means that your jobs will start faster.
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+ ``` ruby
14
+ gem "postpone"
15
+ ```
16
+
17
+ And then execute:
18
+ ```
19
+ $ bundle
20
+ ```
21
+
22
+ Or install it yourself as:
23
+ ```
24
+ $ gem install postpone
25
+ ```
26
+
27
+ ## Invoke
28
+
29
+ Call `postpone` on any given object to *postpone* the execution.
30
+
31
+ ``` ruby
32
+ User.first.postpone.notify!
33
+ ```
34
+
35
+ *Postpone* **cannot** postpone blocks. Why is explained [here](http://stackoverflow.com/a/38588/560073).
36
+
37
+ ``` ruby
38
+ User.first.postpone.notify! { "How do you do?" }
39
+ ```
40
+
41
+ ## Worker
42
+
43
+ *Postpone* is build on top of [beanstalkd](http://kr.github.com/beanstalkd/) and [stalker](https://github.com/adamwiggins/stalker) which means that you need an external worker.
44
+
45
+ ### Creating a worker
46
+
47
+ Create a file called `jobs.rb` and add the following code to it
48
+
49
+ ``` ruby
50
+ require "postpone/worker"
51
+ ```
52
+
53
+ Add your own worker to the same file, if you have any.
54
+ Take a look at the [official stalker repo](https://github.com/han/stalker) for more information.
55
+
56
+ ``` ruby
57
+ Stalker::job "email.send" do |args|
58
+ Pony.send(to: args['to'], subject: "Hello there")
59
+ end
60
+ ```
61
+
62
+ Start your worker using `stalk jobs.rb`
63
+
64
+ ## Hint
65
+
66
+ Keep in mind that the object you are trying to *postpone* needs to be available on both sides.
67
+ So if you're trying to *postpone* an operation on a rails object you need to load the rails environment on the worker side too.
68
+
69
+ ``` ruby
70
+ # Loading rails
71
+ require File.expand_path("../environment", __FILE__)
72
+
73
+ # Loading postpone
74
+ require "postpone/worker"
75
+ ```
76
+
77
+ ## Alternatives
78
+
79
+ - [Delayed job](https://github.com/tobi/delayed_job)
80
+ - [resque](https://github.com/defunkt/resque)
81
+
82
+ ## Testing
83
+
84
+ Start by installing [rspec](https://github.com/dchelimsky/rspec).
85
+ Then, run the tests using `rspec .`
86
+
87
+ ## Contributing
88
+
89
+ 1. Fork it
90
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
91
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
92
+ 4. Push to the branch (`git push origin my-new-feature`)
93
+ 5. Create new Pull Request
94
+
95
+ ## License
96
+
97
+ *Postpone* is released under the *MIT License*.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,2 @@
1
+ require_relative "./postpone/invoke"
2
+ Object.send(:include, Postpone)
@@ -0,0 +1,20 @@
1
+ require "stalker"
2
+
3
+ module Postpone
4
+ def postpone; Invoke.new(self); end
5
+ def self.postpone; Invoke.new(self); end
6
+
7
+ class Invoke
8
+ def initialize(object)
9
+ @object = object
10
+ end
11
+
12
+ def method_missing(method, *args)
13
+ !! Stalker.enqueue("postpone.worker", {
14
+ method: method,
15
+ args: Marshal.dump(args),
16
+ object: Marshal.dump(@object)
17
+ })
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ require "stalker"
2
+
3
+ module Postpone
4
+ class Worker
5
+ def initialize(args)
6
+ Marshal.load(args["object"]).
7
+ send(args["method"], *Marshal.load(args["args"]))
8
+ end
9
+ end
10
+ end
11
+
12
+ Stalker::job "postpone.worker" do |args|
13
+ Postpone::Worker.new(args)
14
+ end
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ Gem::Specification.new do |gem|
3
+ gem.authors = ["Linus Oleander"]
4
+ gem.email = ["linus@oleander.nu"]
5
+ gem.description = %q{Beanstalkd backed asynchronous priority queue}
6
+ gem.summary = %q{Beanstalkd backed asynchronous priority queue}
7
+ gem.homepage = "https://github.com/oleander/postpone-rb"
8
+
9
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
10
+ gem.files = `git ls-files`.split("\n")
11
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
12
+ gem.name = "postpone"
13
+ gem.require_paths = ["lib"]
14
+ gem.version = "0.1.0"
15
+
16
+ gem.add_dependency("stalker")
17
+ gem.add_development_dependency("rspec")
18
+ gem.required_ruby_version = "~> 1.9.0"
19
+ end
@@ -0,0 +1,102 @@
1
+
2
+ describe Postpone::Invoke do
3
+ describe "instance" do
4
+ subject { Example.new }
5
+ it "should invoke stalker, without arguments" do
6
+ Stalker.should_receive(:enqueue).with("postpone.worker", translate({
7
+ args: [],
8
+ object: subject,
9
+ method: :method1
10
+ }))
11
+
12
+ subject.postpone.method1
13
+ end
14
+
15
+ it "should invoke stalker, with arguments" do
16
+ Stalker.should_receive(:enqueue).with("postpone.worker", translate({
17
+ args: ["value1", "value2"],
18
+ object: subject,
19
+ method: :method2
20
+ }))
21
+
22
+ subject.postpone.method2("value1", "value2")
23
+ end
24
+ end
25
+
26
+ describe "class method" do
27
+ subject { Example }
28
+ it "should invoke stalker, without arguments" do
29
+ Stalker.should_receive(:enqueue).with("postpone.worker", translate({
30
+ args: [],
31
+ object: subject,
32
+ method: :method3
33
+ }))
34
+
35
+ subject.postpone.method3
36
+ end
37
+
38
+ it "should invoke stalker, with arguments" do
39
+ Stalker.should_receive(:enqueue).with("postpone.worker", translate({
40
+ args: ["value1", "value2"],
41
+ object: subject,
42
+ method: :method4
43
+ }))
44
+
45
+ subject.postpone.method4("value1", "value2")
46
+ end
47
+ end
48
+ end
49
+
50
+ describe Postpone::Worker do
51
+ describe "instance" do
52
+ subject { Example.new }
53
+
54
+ before(:all) { $method1, $method2 = nil, nil }
55
+
56
+ it "should call instance method, without arguments" do
57
+ Postpone::Worker.new(translate({
58
+ args: [],
59
+ object: subject,
60
+ method: :method1
61
+ }, "string"))
62
+
63
+ $method1.should_not be_nil
64
+ end
65
+
66
+ it "should call instance method, with arguments" do
67
+ Postpone::Worker.new(translate({
68
+ args: ["value1", "value2"],
69
+ object: subject,
70
+ method: :method2
71
+ }, "string"))
72
+
73
+ $method2.should_not be_nil
74
+ end
75
+ end
76
+
77
+ describe "class method" do
78
+ subject { Example }
79
+
80
+ before(:all) { $method3, $method4 = nil, nil }
81
+
82
+ it "should call instance method, without arguments" do
83
+ Postpone::Worker.new(translate({
84
+ args: [],
85
+ object: subject,
86
+ method: :method3
87
+ }, "string"))
88
+
89
+ $method3.should_not be_nil
90
+ end
91
+
92
+ it "should call instance method, with arguments" do
93
+ Postpone::Worker.new(translate({
94
+ args: ["value1", "value2"],
95
+ object: subject,
96
+ method: :method4
97
+ }, "string"))
98
+
99
+ $method4.should_not be_nil
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,30 @@
1
+ require "rspec"
2
+ require_relative "../lib/postpone"
3
+ require_relative "../lib/postpone/worker"
4
+
5
+ module Helpers
6
+ def translate(hash, type = "symbol")
7
+ args = Marshal.dump(hash[:args])
8
+ object = Marshal.dump(hash[:object])
9
+ method = hash[:method]
10
+
11
+ case type
12
+ when "symbol"
13
+ { args: args, object: object, method: method }
14
+ when "string"
15
+ { "args" => args, "object" => object, "method" => method }
16
+ end
17
+ end
18
+ end
19
+
20
+ class Example
21
+ def method1; $method1 = 1; end
22
+ def method2(value1, value2); $method2 = 1; end
23
+ def self.method3; $method3 = 1; end
24
+ def self.method4(value1, value2); $method4 = 1; end
25
+ end
26
+
27
+ RSpec.configure do |config|
28
+ config.mock_with :rspec
29
+ config.include Helpers
30
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: postpone
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Linus Oleander
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-01-26 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: stalker
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: rspec
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :development
36
+ version_requirements: *id002
37
+ description: Beanstalkd backed asynchronous priority queue
38
+ email:
39
+ - linus@oleander.nu
40
+ executables: []
41
+
42
+ extensions: []
43
+
44
+ extra_rdoc_files: []
45
+
46
+ files:
47
+ - .gitignore
48
+ - .rspec
49
+ - Gemfile
50
+ - LICENSE
51
+ - README.md
52
+ - Rakefile
53
+ - lib/postpone.rb
54
+ - lib/postpone/invoke.rb
55
+ - lib/postpone/worker.rb
56
+ - postpone.gemspec
57
+ - spec/postpone_spec.rb
58
+ - spec/spec_helper.rb
59
+ homepage: https://github.com/oleander/postpone-rb
60
+ licenses: []
61
+
62
+ post_install_message:
63
+ rdoc_options: []
64
+
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ~>
71
+ - !ruby/object:Gem::Version
72
+ version: 1.9.0
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ requirements: []
80
+
81
+ rubyforge_project:
82
+ rubygems_version: 1.8.15
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: Beanstalkd backed asynchronous priority queue
86
+ test_files:
87
+ - spec/postpone_spec.rb
88
+ - spec/spec_helper.rb