tennis-jobs 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.markdown +63 -4
- data/bin/tennis +6 -0
- data/lib/tennis/cli.rb +102 -0
- data/lib/tennis/worker/generic.rb +2 -0
- data/lib/tennis/worker/generic/options.rb +10 -0
- data/tennis-jobs.gemspec +3 -3
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 41fd5c9ff7ba286a975e7f6fd69b422564884783
|
4
|
+
data.tar.gz: 02f1abfb9d8045033ab9bc8203b0d05473d4736e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 37dda9596db258dea9c2eb3787bf1b674cca4faa3b4467cca957bd646f7d6ab6e8e76ef3382d8ac9b29f3afa0d73524224094b9b32cd493106061f4e021672cc
|
7
|
+
data.tar.gz: 67dddffbe9393ca3051eea299dcb95974f3a147ba31403070663fe534fce849a68752d33adf28be4a73ffe8dc2ab59478e5a2b42aec383089dea056317b0dc21
|
data/README.markdown
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
This small library is intended to help creating asynchronous jobs
|
2
2
|
using Ruby and RabbitMQ via the Sneakers gem.
|
3
3
|
|
4
|
-
<a href="https://travis-ci.org/nicoolas25/tennis"><img src="https://travis-ci.org/nicoolas25/tennis.svg?branch=master" /></a>
|
5
|
-
<a href="https://codeclimate.com/github/nicoolas25/tennis"><img src="https://codeclimate.com/github/nicoolas25/tennis/badges/gpa.svg" /></a>
|
6
|
-
<a href="https://codeclimate.com/github/nicoolas25/tennis/coverage"><img src="https://codeclimate.com/github/nicoolas25/tennis/badges/coverage.svg" /></a>
|
4
|
+
<a target="_blank" href="https://travis-ci.org/nicoolas25/tennis"><img src="https://travis-ci.org/nicoolas25/tennis.svg?branch=master" /></a>
|
5
|
+
<a target="_blank" href="https://codeclimate.com/github/nicoolas25/tennis"><img src="https://codeclimate.com/github/nicoolas25/tennis/badges/gpa.svg" /></a>
|
6
|
+
<a target="_blank" href="https://codeclimate.com/github/nicoolas25/tennis/coverage"><img src="https://codeclimate.com/github/nicoolas25/tennis/badges/coverage.svg" /></a>
|
7
|
+
<a target="_blank" href="https://rubygems.org/gems/tennis-jobs"><img src="https://badge.fury.io/rb/tennis-jobs.svg" /></a>
|
7
8
|
|
8
9
|
## Features
|
9
10
|
|
@@ -15,12 +16,70 @@ using Ruby and RabbitMQ via the Sneakers gem.
|
|
15
16
|
|
16
17
|
- A `GenericSerializer` handling classes and ActiveRecord objects
|
17
18
|
|
19
|
+
## Configuration
|
20
|
+
|
21
|
+
The background job require a group of processes to handle the tasks you want to
|
22
|
+
do asynchronously. Tennis uses YAML configuration file in order to launch thoses
|
23
|
+
processes.
|
24
|
+
|
25
|
+
``` yaml
|
26
|
+
# tennis.conf.yml
|
27
|
+
group1:
|
28
|
+
exchange: "default"
|
29
|
+
workers: 1
|
30
|
+
classes:
|
31
|
+
- "Scope::MyClass"
|
32
|
+
- "Scope::Model"
|
33
|
+
group2:
|
34
|
+
exchange: "important"
|
35
|
+
workers: 10
|
36
|
+
classes:
|
37
|
+
- "Only::ImportantWorker"
|
38
|
+
```
|
39
|
+
|
40
|
+
Here we see two groups of worker. Each group can be launch with the `tennis`
|
41
|
+
command:
|
42
|
+
|
43
|
+
$ bundle exec tennis group1
|
44
|
+
|
45
|
+
The `workers` options is directly given to sneakers, it will determine the
|
46
|
+
number of subprocesses that will handle the messages, the level of parallelism.
|
47
|
+
|
48
|
+
The classes are the classes that will receive your `execute` or `defer` calls
|
49
|
+
but we'll see that later...
|
50
|
+
|
51
|
+
Also it is possible to add options directly in your workers:
|
52
|
+
|
53
|
+
``` ruby
|
54
|
+
module WorkerHelpers
|
55
|
+
BeforeFork = -> { ActiveRecord::Base.connection_pool.disconnect! rescue nil }
|
56
|
+
AfterFork = -> { ActiveRecord::Base.establish_connection }
|
57
|
+
end
|
58
|
+
|
59
|
+
class MyClass
|
60
|
+
include GenericWorker
|
61
|
+
|
62
|
+
set_option :before_fork, WorkerHelpers::BeforeFork
|
63
|
+
set_option :after_fork, WorkerHelpers::AfterFork
|
64
|
+
set_option :handler, Sneakers::Handlers::MaxretryWithoutErrors
|
65
|
+
|
66
|
+
work do |message|
|
67
|
+
MyActiveRecordModel.create(message: message)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
```
|
71
|
+
|
72
|
+
In this example I use constants to store the Proc options. This is because
|
73
|
+
having different options for the workers of a same group isn't possible. By
|
74
|
+
using this constant, I can have another worker with those same options and put
|
75
|
+
it in the same group.
|
76
|
+
|
18
77
|
## Examples
|
19
78
|
|
20
79
|
Those examples are what we wish to achieve.
|
21
80
|
|
22
81
|
The name of the queue is the name of the class by default and can be reset
|
23
|
-
using sneakers'
|
82
|
+
using sneakers' `YourClass.worker.from_queue` method.
|
24
83
|
|
25
84
|
### Hooks
|
26
85
|
|
data/bin/tennis
ADDED
data/lib/tennis/cli.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require "optparse"
|
3
|
+
require "sneakers"
|
4
|
+
require "sneakers/runner"
|
5
|
+
|
6
|
+
module Tennis
|
7
|
+
class CLI
|
8
|
+
|
9
|
+
DEFAULT_OPTIONS = {
|
10
|
+
config: "./tennis.yml",
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
def self.start
|
14
|
+
options = DEFAULT_OPTIONS.dup
|
15
|
+
OptionParser.new do |opts|
|
16
|
+
opts.banner = "Usage: tennis [options] group"
|
17
|
+
opts.on("-c", "--config FILE", "Set the config file") do |file|
|
18
|
+
options[:config] = file
|
19
|
+
end
|
20
|
+
opts.on("-r", "--require PATH", "Require files before starting") do |path|
|
21
|
+
options[:require] ||= []
|
22
|
+
options[:require] << path
|
23
|
+
end
|
24
|
+
opts.on("-x", "--execute CODE", "Execute code before starting") do |code|
|
25
|
+
options[:execute] ||= []
|
26
|
+
options[:execute] << code
|
27
|
+
end
|
28
|
+
end.parse!
|
29
|
+
options[:group] = ARGV.first
|
30
|
+
new(options).start
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(options)
|
34
|
+
@options = options
|
35
|
+
end
|
36
|
+
|
37
|
+
def start
|
38
|
+
do_require
|
39
|
+
execute_code
|
40
|
+
configure_tennis
|
41
|
+
start_group
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def do_require
|
47
|
+
return unless requires = @options[:require]
|
48
|
+
requires.each { |path| require path } if @options[:require]
|
49
|
+
end
|
50
|
+
|
51
|
+
def execute_code
|
52
|
+
return unless codes = @options[:execute]
|
53
|
+
codes.each { |code| eval code }
|
54
|
+
end
|
55
|
+
|
56
|
+
def configure_tennis
|
57
|
+
Tennis.configure do |config|
|
58
|
+
config.async = true
|
59
|
+
config.exchange = group["exchange"]
|
60
|
+
config.workers = group["workers"].to_i
|
61
|
+
config.logger = Logger.new(STDOUT)
|
62
|
+
config.logger.level = Logger::WARN
|
63
|
+
config.sneakers_options = sneakers_options
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def sneakers_options
|
68
|
+
classes.map(&:options).each_with_object({}) do |options, all_options|
|
69
|
+
merge_options(all_options, options)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def merge_options(target, options)
|
74
|
+
options.each do |name, value|
|
75
|
+
if target[name].nil?
|
76
|
+
target[name] = value
|
77
|
+
elsif target[name] != value
|
78
|
+
fail "Workers shouldn't have different '#{name}' options"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def start_group
|
84
|
+
Sneakers::Runner.new(classes.map(&:worker)).run
|
85
|
+
end
|
86
|
+
|
87
|
+
def classes
|
88
|
+
@classes ||= group["classes"].map do |name|
|
89
|
+
Object.const_get(name)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def group
|
94
|
+
@group ||= config[@options[:group]]
|
95
|
+
end
|
96
|
+
|
97
|
+
def config
|
98
|
+
YAML.load_file(@options[:config])
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
@@ -4,10 +4,12 @@ module Tennis
|
|
4
4
|
|
5
5
|
autoload :BeforeHook, "tennis/worker/generic/before_hook"
|
6
6
|
autoload :Serialize, "tennis/worker/generic/serialize"
|
7
|
+
autoload :Options, "tennis/worker/generic/options"
|
7
8
|
|
8
9
|
def self.included(base)
|
9
10
|
base.extend BeforeHook
|
10
11
|
base.extend Serialize
|
12
|
+
base.extend Options
|
11
13
|
base.extend DSL
|
12
14
|
base.worker = Class.new do
|
13
15
|
@@parent = base
|
data/tennis-jobs.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "tennis-jobs"
|
7
|
-
spec.version = "0.
|
7
|
+
spec.version = "0.2.0"
|
8
8
|
spec.authors = ["Nicolas ZERMATI"]
|
9
9
|
spec.email = ["nicoolas25@gmail.com"]
|
10
10
|
|
@@ -14,8 +14,8 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
-
spec.bindir = "
|
18
|
-
spec.executables = spec.files.grep(%r{^
|
17
|
+
spec.bindir = "bin"
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_runtime_dependency "sneakers"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tennis-jobs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicolas ZERMATI
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-09-
|
11
|
+
date: 2015-09-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sneakers
|
@@ -125,7 +125,8 @@ dependencies:
|
|
125
125
|
description: A small background job library on top of sneakers.
|
126
126
|
email:
|
127
127
|
- nicoolas25@gmail.com
|
128
|
-
executables:
|
128
|
+
executables:
|
129
|
+
- tennis
|
129
130
|
extensions: []
|
130
131
|
extra_rdoc_files: []
|
131
132
|
files:
|
@@ -137,16 +138,19 @@ files:
|
|
137
138
|
- LICENSE.txt
|
138
139
|
- README.markdown
|
139
140
|
- Rakefile
|
141
|
+
- bin/tennis
|
140
142
|
- examples/deferable.rb
|
141
143
|
- examples/example.rb
|
142
144
|
- examples/serializer.rb
|
143
145
|
- lib/tennis.rb
|
146
|
+
- lib/tennis/cli.rb
|
144
147
|
- lib/tennis/configuration.rb
|
145
148
|
- lib/tennis/serializer/generic.rb
|
146
149
|
- lib/tennis/worker/deferable.rb
|
147
150
|
- lib/tennis/worker/deferable/action.rb
|
148
151
|
- lib/tennis/worker/generic.rb
|
149
152
|
- lib/tennis/worker/generic/before_hook.rb
|
153
|
+
- lib/tennis/worker/generic/options.rb
|
150
154
|
- lib/tennis/worker/generic/serialize.rb
|
151
155
|
- tennis-jobs.gemspec
|
152
156
|
homepage: https://github.com/nicoolas25/tennis
|