bg 0.0.3 → 0.0.4
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +27 -17
- data/README.md +12 -4
- data/Rakefile +11 -0
- data/lib/bg/deferrable.rb +20 -5
- data/lib/bg/version.rb +1 -1
- data/test/backgroundable_object.rb +30 -0
- data/test/bg/asyncable_test.rb +13 -0
- data/test/bg/deferrable_test.rb +79 -0
- data/test/bg/deferred_method_call_test.rb +39 -0
- data/test/test_helper.rb +21 -0
- metadata +70 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b59fee4ea49e20b0f003c82d4e88cfe8944ba00
|
4
|
+
data.tar.gz: 5e1d394c114e456a75d342f566777a79f855cf49
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f98b49309738b49b5a2e91d361d7a1a4a7edde4547edade187374461d3be98d4c870820e4488ed57ae5e75b268cc673926b2a18cff7b7d43da41be3db645677
|
7
|
+
data.tar.gz: e19f24f3030ca8f696859d0b051ca5225095044b978ea68bea7d1cff8e55a834c485393507e509684d354de6b3b130028eb3ef5b8398fb113cf7335ab3712470
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
bg (0.0.
|
4
|
+
bg (0.0.4)
|
5
5
|
activejob (>= 5.0)
|
6
6
|
activerecord (>= 5.0)
|
7
7
|
concurrent-ruby (>= 1.0)
|
@@ -27,39 +27,45 @@ GEM
|
|
27
27
|
arel (7.1.2)
|
28
28
|
binding_of_caller (0.7.2)
|
29
29
|
debug_inspector (>= 0.0.1)
|
30
|
-
byebug (9.0.6)
|
31
30
|
coderay (1.1.1)
|
32
31
|
concurrent-ruby (1.0.2)
|
32
|
+
coveralls (0.8.13)
|
33
|
+
json (~> 1.8)
|
34
|
+
simplecov (~> 0.11.0)
|
35
|
+
term-ansicolor (~> 1.3)
|
36
|
+
thor (~> 0.19.1)
|
37
|
+
tins (~> 1.6.0)
|
33
38
|
debug_inspector (0.0.2)
|
39
|
+
docile (1.1.5)
|
34
40
|
globalid (0.3.7)
|
35
41
|
activesupport (>= 4.1.0)
|
36
42
|
i18n (0.7.0)
|
37
|
-
|
43
|
+
json (1.8.3)
|
38
44
|
method_source (0.8.2)
|
39
45
|
minitest (5.9.1)
|
40
|
-
os (0.9.6)
|
41
46
|
pry (0.10.4)
|
42
47
|
coderay (~> 1.1.0)
|
43
48
|
method_source (~> 0.8.1)
|
44
49
|
slop (~> 3.4)
|
45
|
-
pry-
|
46
|
-
|
47
|
-
pry (~> 0.10)
|
48
|
-
pry-rescue (1.4.4)
|
49
|
-
interception (>= 0.5)
|
50
|
-
pry
|
50
|
+
pry-nav (0.2.4)
|
51
|
+
pry (>= 0.9.10, < 0.11.0)
|
51
52
|
pry-stack_explorer (0.4.9.2)
|
52
53
|
binding_of_caller (>= 0.7)
|
53
54
|
pry (>= 0.9.11)
|
54
|
-
|
55
|
-
|
56
|
-
pry
|
57
|
-
pry-byebug
|
58
|
-
pry-rescue
|
59
|
-
pry-stack_explorer
|
55
|
+
purdytest (2.0.0)
|
56
|
+
minitest (~> 5.5)
|
60
57
|
rake (11.3.0)
|
58
|
+
simplecov (0.11.2)
|
59
|
+
docile (~> 1.1.0)
|
60
|
+
json (~> 1.8)
|
61
|
+
simplecov-html (~> 0.10.0)
|
62
|
+
simplecov-html (0.10.0)
|
61
63
|
slop (3.6.0)
|
64
|
+
term-ansicolor (1.3.2)
|
65
|
+
tins (~> 1.0)
|
66
|
+
thor (0.19.1)
|
62
67
|
thread_safe (0.3.5)
|
68
|
+
tins (1.6.0)
|
63
69
|
tzinfo (1.2.2)
|
64
70
|
thread_safe (~> 0.1)
|
65
71
|
|
@@ -68,7 +74,11 @@ PLATFORMS
|
|
68
74
|
|
69
75
|
DEPENDENCIES
|
70
76
|
bg!
|
71
|
-
|
77
|
+
coveralls
|
78
|
+
pry
|
79
|
+
pry-nav
|
80
|
+
pry-stack_explorer
|
81
|
+
purdytest
|
72
82
|
rake
|
73
83
|
|
74
84
|
BUNDLED WITH
|
data/README.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
[](http://blog.codinghorror.com/the-best-code-is-no-code-at-all/)
|
2
|
+
[](https://codeclimate.com/github/hopsoft/bg)
|
3
|
+
[](https://gemnasium.com/hopsoft/bg)
|
4
|
+
[](https://travis-ci.org/hopsoft/bg)
|
5
|
+
[](https://coveralls.io/r/hopsoft/bg?branch=master)
|
6
|
+
[](http://rubygems.org/gems/bg)
|
7
|
+
|
1
8
|
# Bg
|
2
9
|
|
3
10
|
## Non-blocking ActiveRecord method invocation
|
@@ -31,12 +38,13 @@ user.defer(queue: :low, wait: 5.minutes).do_hard_work
|
|
31
38
|
|
32
39
|
## Provisos
|
33
40
|
|
34
|
-
Bg leverages [GlobalID](https://github.com/rails/globalid) to marshal ActiveRecord instances across thread & process boundaries.
|
41
|
+
Bg leverages [GlobalID::Identification](https://github.com/rails/globalid) to marshal ActiveRecord instances across thread & process boundaries.
|
35
42
|
This means that state is not shared between the main process/thread with the process/thread actually executing the method.
|
36
43
|
|
37
|
-
*
|
38
|
-
*
|
39
|
-
|
44
|
+
* __Do not__ depend on lexically scoped bindings when invoking methods with `Bg::Deferrable`.
|
45
|
+
* __Do not__ pass unmarshallable types as arguments with `Bg::Deferrable`.
|
46
|
+
`Bg::Deferrable` will prepare arguments for enqueuing, but best practice is to follow
|
47
|
+
Sidekiq's [simple parameters](https://github.com/mperham/sidekiq/wiki/Best-Practices#1-make-your-job-parameters-small-and-simple) rule.
|
40
48
|
|
41
49
|
### Examples
|
42
50
|
|
data/Rakefile
CHANGED
data/lib/bg/deferrable.rb
CHANGED
@@ -10,6 +10,23 @@ module Bg
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
def self.make_enqueable(value)
|
14
|
+
case value
|
15
|
+
when ::Hash then
|
16
|
+
value.each.with_object({}) do |(key, val), memo|
|
17
|
+
memo[key.to_s] = make_enqueable(val)
|
18
|
+
end
|
19
|
+
when ::Array then
|
20
|
+
value.map { |val| make_enqueable val }
|
21
|
+
when ::Symbol then
|
22
|
+
value.to_s
|
23
|
+
when ::Date, ::Time, ::DateTime then
|
24
|
+
value.respond_to?(:iso8601) ? value.iso8601 : value.to_s
|
25
|
+
else
|
26
|
+
value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
13
30
|
attr_reader :object, :queue, :wait
|
14
31
|
|
15
32
|
def initialize(object, queue: :default, wait: 0)
|
@@ -23,11 +40,9 @@ module Bg
|
|
23
40
|
if object.respond_to? name
|
24
41
|
raise ::ArgumentError.new("blocks are not supported") if block_given?
|
25
42
|
begin
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
job = ::Bg::DeferredMethodCallJob.set(queue: queue).perform_later object, name.to_s, *args
|
30
|
-
end
|
43
|
+
queue_args = { queue: queue }
|
44
|
+
queue_args[:wait] = wait if wait > 0
|
45
|
+
job = ::Bg::DeferredMethodCallJob.set(**queue_args).perform_later object, name.to_s, *self.class.make_enqueable(args)
|
31
46
|
rescue ::StandardError => e
|
32
47
|
raise ::ArgumentError.new("Failed to background method call! <#{object.class.name}##{name}> #{e.message}")
|
33
48
|
ensure
|
data/lib/bg/version.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
require "globalid"
|
2
|
+
|
3
|
+
class Bg::BackgroundableObject
|
4
|
+
include ::GlobalID::Identification
|
5
|
+
|
6
|
+
def self.find(id)
|
7
|
+
new id
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_accessor :id
|
11
|
+
|
12
|
+
def initialize(id)
|
13
|
+
@id = id
|
14
|
+
end
|
15
|
+
|
16
|
+
def update(attrs={})
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
def wait(seconds=0)
|
21
|
+
sleep seconds.to_i
|
22
|
+
true
|
23
|
+
end
|
24
|
+
|
25
|
+
def eigen
|
26
|
+
class << self
|
27
|
+
self
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative "../test_helper"
|
2
|
+
|
3
|
+
class Bg::AsyncableTest < ::ActiveSupport::TestCase
|
4
|
+
|
5
|
+
test "slow io bound method invocations run in parallel" do
|
6
|
+
obj = ::Bg::BackgroundableObject.new(:example)
|
7
|
+
obj.eigen.send :include, ::Bg::Asyncable::Behavior
|
8
|
+
start = Time.now
|
9
|
+
10.times { obj.async.wait 1 }
|
10
|
+
assert (Time.now - start) <= 1.1
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require_relative "../test_helper"
|
2
|
+
|
3
|
+
class Bg::DeferrableTest < ::ActiveSupport::TestCase
|
4
|
+
|
5
|
+
setup do
|
6
|
+
@deferrable = ::Bg::Deferrable.new(::Bg::BackgroundableObject.new(:example))
|
7
|
+
end
|
8
|
+
|
9
|
+
test ".make_enqueable with Symbol" do
|
10
|
+
value = ::Bg::Deferrable.make_enqueable(:foo)
|
11
|
+
assert value == "foo"
|
12
|
+
end
|
13
|
+
|
14
|
+
test ".make_enqueable with Date" do
|
15
|
+
date = ::Date.today
|
16
|
+
value = ::Bg::Deferrable.make_enqueable(date)
|
17
|
+
assert value == date.iso8601
|
18
|
+
end
|
19
|
+
|
20
|
+
test ".make_enqueable with Time" do
|
21
|
+
time = ::Time.now
|
22
|
+
value = ::Bg::Deferrable.make_enqueable(time)
|
23
|
+
assert value == time.iso8601
|
24
|
+
end
|
25
|
+
|
26
|
+
test ".make_enqueable with DateTime" do
|
27
|
+
date_time = ::DateTime.now
|
28
|
+
value = ::Bg::Deferrable.make_enqueable(date_time)
|
29
|
+
assert value == date_time.iso8601
|
30
|
+
end
|
31
|
+
|
32
|
+
test ".make_enqueable with Array" do
|
33
|
+
date_time = ::DateTime.now
|
34
|
+
list = [:foo, "bar", true, date_time]
|
35
|
+
value = ::Bg::Deferrable.make_enqueable(list)
|
36
|
+
assert value == ["foo", "bar", true, date_time.iso8601]
|
37
|
+
end
|
38
|
+
|
39
|
+
test ".make_enqueable with nested Array" do
|
40
|
+
date_time = ::DateTime.now
|
41
|
+
list = [:foo, "bar", true, date_time]
|
42
|
+
list << list.dup
|
43
|
+
value = ::Bg::Deferrable.make_enqueable(list)
|
44
|
+
expected = ["foo", "bar", true, date_time.iso8601]
|
45
|
+
expected << expected.dup
|
46
|
+
assert value == expected
|
47
|
+
end
|
48
|
+
|
49
|
+
test ".make_enqueable with Hash" do
|
50
|
+
date_time = ::DateTime.now
|
51
|
+
hash = { a: :foo, b: "bar", c: true, d: date_time }
|
52
|
+
value = ::Bg::Deferrable.make_enqueable(hash)
|
53
|
+
assert value == { "a" => "foo", "b" => "bar", "c" => true, "d" => date_time.iso8601 }
|
54
|
+
end
|
55
|
+
|
56
|
+
test ".make_enqueable with nested Hash" do
|
57
|
+
date_time = ::DateTime.now
|
58
|
+
hash = { a: :foo, b: "bar", c: true, d: date_time }
|
59
|
+
hash[:e] = hash.dup
|
60
|
+
value = ::Bg::Deferrable.make_enqueable(hash)
|
61
|
+
expected = { "a" => "foo", "b" => "bar", "c" => true, "d" => date_time.iso8601 }
|
62
|
+
expected["e"] = expected.dup
|
63
|
+
assert value == expected
|
64
|
+
end
|
65
|
+
|
66
|
+
test ".make_enqueable with complex Hash" do
|
67
|
+
time = ::Time.now
|
68
|
+
hash = { a: :foo, b: time, c: { a: :bar, b: time.dup }, d: [:baz, time.dup, {a: :wat, b: time.dup, c: [a: time.dup]}] }
|
69
|
+
value = ::Bg::Deferrable.make_enqueable(hash)
|
70
|
+
expected = {
|
71
|
+
"a" => "foo",
|
72
|
+
"b" => time.iso8601,
|
73
|
+
"c" => { "a" => "bar", "b" => time.iso8601 },
|
74
|
+
"d" => [ "baz", time.iso8601, { "a" => "wat", "b" => time.iso8601, "c" => [{"a" => time.iso8601}] } ]
|
75
|
+
}
|
76
|
+
assert value == expected
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative "../test_helper"
|
2
|
+
require "active_job/test_helper"
|
3
|
+
|
4
|
+
class Bg::DeferredMethodCallJobTest < ::ActiveJob::TestCase
|
5
|
+
|
6
|
+
test "enqueues with no args" do
|
7
|
+
assert_enqueued_with job: ::Bg::DeferredMethodCallJob do
|
8
|
+
obj = ::Bg::BackgroundableObject.new(:example)
|
9
|
+
obj.eigen.send :include, ::Bg::Deferrable::Behavior
|
10
|
+
obj.defer.update
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
test "enqueues with simple args" do
|
15
|
+
assert_enqueued_with job: ::Bg::DeferredMethodCallJob do
|
16
|
+
obj = ::Bg::BackgroundableObject.new(:example)
|
17
|
+
obj.eigen.send :include, ::Bg::Deferrable::Behavior
|
18
|
+
obj.defer.update foo: true, bar: "baz"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
test "enqueues with globalid args" do
|
23
|
+
assert_enqueued_with job: ::Bg::DeferredMethodCallJob do
|
24
|
+
parent = ::Bg::BackgroundableObject.new(:parent)
|
25
|
+
parent.eigen.send :include, ::Bg::Deferrable::Behavior
|
26
|
+
parent.defer.update child: ::Bg::BackgroundableObject.new(:child)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
test "enqueues with complex args" do
|
31
|
+
assert_enqueued_with job: ::Bg::DeferredMethodCallJob do
|
32
|
+
parent = ::Bg::BackgroundableObject.new(:parent)
|
33
|
+
parent.eigen.send :include, ::Bg::Deferrable::Behavior
|
34
|
+
parent.defer.update children: [::Bg::BackgroundableObject.new(:child1), ::Bg::BackgroundableObject.new(:child2)],
|
35
|
+
foo: { bar: [:baz, Date.new, Time.new, DateTime.new] }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require "coveralls"
|
2
|
+
Coveralls.wear!
|
3
|
+
require_relative "../lib/bg"
|
4
|
+
require_relative "backgroundable_object"
|
5
|
+
require "minitest/autorun"
|
6
|
+
require "purdytest"
|
7
|
+
#require "pry"
|
8
|
+
#require "pry-nav"
|
9
|
+
#require "pry-stack_explorer"
|
10
|
+
|
11
|
+
::ActiveSupport::TestCase.test_order = :random
|
12
|
+
::GlobalID.app = "test"
|
13
|
+
::ActiveRecord::Base = Class.new do
|
14
|
+
def connection_pool
|
15
|
+
Class.new do
|
16
|
+
def with_connection
|
17
|
+
yield
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Hopkins
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -81,7 +81,63 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: purdytest
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: coveralls
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: pry
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: pry-nav
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: pry-stack_explorer
|
85
141
|
requirement: !ruby/object:Gem::Requirement
|
86
142
|
requirements:
|
87
143
|
- - ">="
|
@@ -113,6 +169,11 @@ files:
|
|
113
169
|
- lib/bg/deferrable.rb
|
114
170
|
- lib/bg/deferred_method_call_job.rb
|
115
171
|
- lib/bg/version.rb
|
172
|
+
- test/backgroundable_object.rb
|
173
|
+
- test/bg/asyncable_test.rb
|
174
|
+
- test/bg/deferrable_test.rb
|
175
|
+
- test/bg/deferred_method_call_test.rb
|
176
|
+
- test/test_helper.rb
|
116
177
|
homepage: https://github.com/hopsoft/bg
|
117
178
|
licenses:
|
118
179
|
- MIT
|
@@ -137,4 +198,9 @@ rubygems_version: 2.5.1
|
|
137
198
|
signing_key:
|
138
199
|
specification_version: 4
|
139
200
|
summary: ''
|
140
|
-
test_files:
|
201
|
+
test_files:
|
202
|
+
- test/backgroundable_object.rb
|
203
|
+
- test/bg/asyncable_test.rb
|
204
|
+
- test/bg/deferrable_test.rb
|
205
|
+
- test/bg/deferred_method_call_test.rb
|
206
|
+
- test/test_helper.rb
|