aservice 0.0.2
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 +7 -0
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/.rubocop.yml +39 -0
- data/Gemfile +5 -0
- data/README.md +7 -0
- data/aservice.gemspec +26 -0
- data/lib/aservice.rb +67 -0
- data/lib/aservice/callback.rb +57 -0
- data/lib/aservice/config.rb +28 -0
- data/lib/aservice/worker/aservice_worker.rb +10 -0
- data/lib/aservice/worker/worker.rb +20 -0
- data/lib/sidekiq/middleware/callback_middleware.rb +28 -0
- metadata +166 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 79bff4730e2fb2c8fa887a439ea31957acc798528dd751d0b2ef129f424dd004
|
4
|
+
data.tar.gz: 340923d749844cfdb527b4935856b58761544da946af1c478e0635b9d0a372ef
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 58514c9c2ebf6b153c4657a8fb00625fc27ee3570b326acbe773b511a73a731acae4af277995b65cb93723d00dc12ef104c908dd9dcbede078c2fa98a996b457
|
7
|
+
data.tar.gz: e8706e954ba0be5e5dfdca059d6b3996224c43e8a2bf474c58a1854b33d78481b0116f5636adb28132267d4ece6d1b7ee8aae809449eac73cc12c9f3cd40816b
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
|
2
|
+
AllCops:
|
3
|
+
TargetRubyVersion: 2.5
|
4
|
+
Include:
|
5
|
+
- "lib/**/*.rb"
|
6
|
+
- "spec/**/*.rb"
|
7
|
+
Exclude:
|
8
|
+
- "bin/**/*"
|
9
|
+
- "examples/*"
|
10
|
+
- "spec/support/*"
|
11
|
+
- "Gemfile"
|
12
|
+
- "Rakefile"
|
13
|
+
- "*.gemspec"
|
14
|
+
DisplayCopNames: true
|
15
|
+
StyleGuideCopsOnly: false
|
16
|
+
|
17
|
+
Style/MethodMissingSuper:
|
18
|
+
Enabled: false
|
19
|
+
|
20
|
+
Style/Documentation:
|
21
|
+
Exclude:
|
22
|
+
- "spec/**/*.rb"
|
23
|
+
|
24
|
+
Style/BlockDelimiters:
|
25
|
+
Exclude:
|
26
|
+
- "spec/**/*.rb"
|
27
|
+
|
28
|
+
Metrics/MethodLength:
|
29
|
+
Exclude:
|
30
|
+
- "spec/**/*.rb"
|
31
|
+
|
32
|
+
Layout/LineLength:
|
33
|
+
Max: 120
|
34
|
+
Exclude:
|
35
|
+
- "spec/**/*.rb"
|
36
|
+
|
37
|
+
Metrics/BlockLength:
|
38
|
+
Exclude:
|
39
|
+
- "spec/**/*.rb"
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Aservice gem allow you to execute your services in background as a sidekiq jod.
|
2
|
+
|
3
|
+
Include Aservice into your class and [method_name]_async and [method_name]_after will be available.
|
4
|
+
|
5
|
+
[method_name]_async call method in sidekiq background job.
|
6
|
+
And [method_name]_after accepts sidekiq job as a first argument and would call method only when job will be successfully completed.
|
7
|
+
Check examples folder for example
|
data/aservice.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'aservice'
|
5
|
+
s.version = '0.0.2'
|
6
|
+
s.date = '2020-07-07'
|
7
|
+
s.summary = 'Aservice'
|
8
|
+
s.description = 'Gem for running services asynchroniously'
|
9
|
+
s.authors = ['Aleksandr Korotkikh']
|
10
|
+
s.email = 'koralvas@gmail.com'
|
11
|
+
s.homepage =
|
12
|
+
'https://github.com/SanderMander/aservice'
|
13
|
+
s.license = 'MIT'
|
14
|
+
s.files = `git ls-files -z`.split("\x0").reject do |f|
|
15
|
+
f.match(%r{^(spec|examples)/})
|
16
|
+
end
|
17
|
+
s.require_paths = ['lib']
|
18
|
+
s.add_development_dependency 'bundler', '~> 2'
|
19
|
+
s.add_development_dependency 'pry-byebug'
|
20
|
+
s.add_development_dependency 'rake', '>= 12.3.3'
|
21
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
22
|
+
s.add_development_dependency 'rubocop'
|
23
|
+
s.add_dependency 'anyway_config', '>= 2.0.0'
|
24
|
+
s.add_dependency('sidekiq', ['>= 4.2.1'])
|
25
|
+
s.add_dependency('sidekiq-status', ['>= 1.1.4'])
|
26
|
+
end
|
data/lib/aservice.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sidekiq'
|
4
|
+
require 'sidekiq-status'
|
5
|
+
require 'anyway_config'
|
6
|
+
require_relative 'aservice/config.rb'
|
7
|
+
require_relative 'aservice/worker/worker.rb'
|
8
|
+
require_relative 'aservice/worker/aservice_worker.rb'
|
9
|
+
require_relative 'aservice/callback.rb'
|
10
|
+
require_relative 'sidekiq/middleware/callback_middleware.rb'
|
11
|
+
|
12
|
+
# Main mixin which provide Asynchronious service call
|
13
|
+
module Aservice
|
14
|
+
def self.included(base)
|
15
|
+
base.class_eval do
|
16
|
+
extend ClassMethods
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Class methods for service.
|
21
|
+
module ClassMethods
|
22
|
+
def call_async(*args)
|
23
|
+
perform(:async, 'call', args)
|
24
|
+
end
|
25
|
+
|
26
|
+
def call_after(jid, *args)
|
27
|
+
args = [] if args.nil?
|
28
|
+
perform(:after, 'call', args.unshift(jid))
|
29
|
+
end
|
30
|
+
|
31
|
+
def respond_to_missing?(method, _)
|
32
|
+
return false if method =~ /_(async|after)$/
|
33
|
+
end
|
34
|
+
|
35
|
+
def method_missing(method, *args)
|
36
|
+
method = method.to_s
|
37
|
+
if method =~ /_async$/
|
38
|
+
method = method.sub(/.*\K_async/, '')
|
39
|
+
perform(:async, method, args)
|
40
|
+
elsif method =~ /_after$/
|
41
|
+
method = method.sub(/.*\K_after/, '')
|
42
|
+
perform(:after, method, args)
|
43
|
+
else
|
44
|
+
raise_no_method_error("No method: #{method} for class: #{AserviceWorker.name}")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def perform(type, method, args)
|
51
|
+
worker = AserviceWorker.set(queue: Aservice::Config.queue)
|
52
|
+
raise_no_method_error("No method: #{method} for class: #{name}") unless respond_to?(method.to_sym)
|
53
|
+
return worker.perform_async(name, method, *args) if type == :async
|
54
|
+
|
55
|
+
jid = args.shift
|
56
|
+
if Sidekiq::Status.complete?(jid)
|
57
|
+
worker.perform_async(name, method, *args)
|
58
|
+
else
|
59
|
+
worker.perform_after(jid, name, method, *args)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def raise_no_method_error(msg)
|
64
|
+
raise NoMethodError, msg
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Aservice
|
4
|
+
# Sidekiq job callbacks
|
5
|
+
class Callback
|
6
|
+
class << self
|
7
|
+
def add(jid, class_name, method, args)
|
8
|
+
opt = {
|
9
|
+
'class' => class_name,
|
10
|
+
'method' => method,
|
11
|
+
'args' => args
|
12
|
+
}
|
13
|
+
Sidekiq.redis do |conn|
|
14
|
+
conn.multi do
|
15
|
+
conn.rpush(key(jid), opt.to_json)
|
16
|
+
conn.expire(key(jid), Aservice::Config.callbacks_expiration)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def success(job)
|
22
|
+
while (opt = pop_next(job['jid']))
|
23
|
+
execute_service(opt['class'], opt['method'], opt['args'])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def failure(job)
|
28
|
+
clear_stack(job['jid'])
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def execute_service(class_name, method, args)
|
34
|
+
Kernel.const_get(class_name).send(method, *args)
|
35
|
+
end
|
36
|
+
|
37
|
+
def pop_next(jid)
|
38
|
+
opt = Sidekiq.redis do |conn|
|
39
|
+
conn.lpop(key(jid))
|
40
|
+
end
|
41
|
+
return false if opt.nil?
|
42
|
+
|
43
|
+
JSON.parse(opt)
|
44
|
+
end
|
45
|
+
|
46
|
+
def clear_stack(jid)
|
47
|
+
Sidekiq.redis do |conn|
|
48
|
+
conn.del(key(jid))
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def key(jid)
|
53
|
+
"#{Aservice::Config.redis_prefix}_#{jid}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Aservice
|
4
|
+
# anyway config wrapper
|
5
|
+
class Config < Anyway::Config
|
6
|
+
config_name :aservice
|
7
|
+
|
8
|
+
attr_config logger: Logger.new($stdout),
|
9
|
+
severity: Logger::Severity::DEBUG,
|
10
|
+
queue: 'default',
|
11
|
+
status_expiration: 60 * 30,
|
12
|
+
redis_prefix: 'AC',
|
13
|
+
callbacks_expiration: 60 * 30
|
14
|
+
def self.instance
|
15
|
+
@config ||= new
|
16
|
+
yield @config if block_given?
|
17
|
+
@config
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.respond_to_missing?(_name, _)
|
21
|
+
instance.respond_to?(method)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.method_missing(method)
|
25
|
+
instance.send(method)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Aservice
|
4
|
+
# Mixin which define perform_after method
|
5
|
+
module Worker
|
6
|
+
def self.included(base)
|
7
|
+
base.include Sidekiq::Worker
|
8
|
+
base.include Sidekiq::Status::Worker
|
9
|
+
Sidekiq::Worker::Setter.class_eval do
|
10
|
+
def perform_after(jid, class_name, method, *args)
|
11
|
+
Aservice::Callback.add(jid, class_name, method, args)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def expiration
|
16
|
+
Aservice::Config.status_expiration
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sidekiq
|
4
|
+
module Middleware
|
5
|
+
# Middleware which executes callbacks
|
6
|
+
class CallbackMiddleware
|
7
|
+
def call(_worker_class, job, _queue)
|
8
|
+
yield
|
9
|
+
Aservice::Callback.success(job)
|
10
|
+
rescue StandardError => e
|
11
|
+
Aservice::Callback.failure(job)
|
12
|
+
raise e
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
Sidekiq.configure_client do |config|
|
19
|
+
Sidekiq::Status.configure_client_middleware config
|
20
|
+
end
|
21
|
+
|
22
|
+
Sidekiq.configure_server do |config|
|
23
|
+
Sidekiq::Status.configure_server_middleware config
|
24
|
+
Sidekiq::Status.configure_client_middleware config
|
25
|
+
config.server_middleware do |chain|
|
26
|
+
chain.add Sidekiq::Middleware::CallbackMiddleware
|
27
|
+
end
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aservice
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Aleksandr Korotkikh
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-07-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry-byebug
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 12.3.3
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 12.3.3
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: anyway_config
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 2.0.0
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 2.0.0
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: sidekiq
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 4.2.1
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 4.2.1
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: sidekiq-status
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.1.4
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 1.1.4
|
125
|
+
description: Gem for running services asynchroniously
|
126
|
+
email: koralvas@gmail.com
|
127
|
+
executables: []
|
128
|
+
extensions: []
|
129
|
+
extra_rdoc_files: []
|
130
|
+
files:
|
131
|
+
- ".gitignore"
|
132
|
+
- ".rspec"
|
133
|
+
- ".rubocop.yml"
|
134
|
+
- Gemfile
|
135
|
+
- README.md
|
136
|
+
- aservice.gemspec
|
137
|
+
- lib/aservice.rb
|
138
|
+
- lib/aservice/callback.rb
|
139
|
+
- lib/aservice/config.rb
|
140
|
+
- lib/aservice/worker/aservice_worker.rb
|
141
|
+
- lib/aservice/worker/worker.rb
|
142
|
+
- lib/sidekiq/middleware/callback_middleware.rb
|
143
|
+
homepage: https://github.com/SanderMander/aservice
|
144
|
+
licenses:
|
145
|
+
- MIT
|
146
|
+
metadata: {}
|
147
|
+
post_install_message:
|
148
|
+
rdoc_options: []
|
149
|
+
require_paths:
|
150
|
+
- lib
|
151
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
152
|
+
requirements:
|
153
|
+
- - ">="
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '0'
|
156
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0'
|
161
|
+
requirements: []
|
162
|
+
rubygems_version: 3.0.6
|
163
|
+
signing_key:
|
164
|
+
specification_version: 4
|
165
|
+
summary: Aservice
|
166
|
+
test_files: []
|