errands 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/errands/runner.rb +179 -0
- data/lib/errands/version.rb +3 -0
- data/lib/errands.rb +3 -0
- metadata +89 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a781f76605abb3a1044de0fe07eeb8239e747f17
|
4
|
+
data.tar.gz: 24ab0e0c763815f8250ba72ebf8a72c98eee9ec0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0f2c8a6784b251e01f897004db3249c606ae129e421d7137481789732d9690a5a5384df3f559324ef01f7a2acba78a37b4b191eff432c147a7555adc95993c2b
|
7
|
+
data.tar.gz: 8faf6c10f519130311a048d71d0b0c80a30d6e8a69bdca20cb8a4429b7cd13d0d5f265bebd5388622b433801841fbc2f2172873bb9f672cd3aa63217b4d6bbf9
|
@@ -0,0 +1,179 @@
|
|
1
|
+
module Errands
|
2
|
+
|
3
|
+
module Runner
|
4
|
+
|
5
|
+
module ThreadAccessors
|
6
|
+
|
7
|
+
def thread_accessors(*accessors)
|
8
|
+
accessors.each do |a|
|
9
|
+
define_method a, -> { our[a] }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
class ImplementationError < StandardError; end
|
16
|
+
|
17
|
+
%w|job process|.each do |m|
|
18
|
+
define_method m do |*_|
|
19
|
+
raise method(__method__).owner::ImplementationError,
|
20
|
+
"#{__method__} has to be implemented in client class"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.included(klass)
|
25
|
+
klass.extend ThreadAccessors
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_accessor :running_mode
|
29
|
+
|
30
|
+
def run(options = startup)
|
31
|
+
start options
|
32
|
+
our[:events] = []
|
33
|
+
|
34
|
+
loop do
|
35
|
+
errands *our[:events].shift if our[:events].any?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def start(options = startup)
|
40
|
+
our.merge! options
|
41
|
+
starter
|
42
|
+
end
|
43
|
+
|
44
|
+
def my
|
45
|
+
Thread.current[:runner] ||= {}
|
46
|
+
end
|
47
|
+
|
48
|
+
def his(t, k, v = nil)
|
49
|
+
t[:runner] ||= {}
|
50
|
+
v ? t[:runner][k] = v : t[:runner][k]
|
51
|
+
end
|
52
|
+
|
53
|
+
def our
|
54
|
+
Thread.main[:runner] ||= {}
|
55
|
+
end
|
56
|
+
|
57
|
+
def starter
|
58
|
+
running do
|
59
|
+
loop do
|
60
|
+
if secure_check :worker, :alive?
|
61
|
+
sleep 1
|
62
|
+
else
|
63
|
+
secure_check :worker, :join
|
64
|
+
worker
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
errands :stop, :starter
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def worker
|
73
|
+
our[:work_done] = false
|
74
|
+
|
75
|
+
running do
|
76
|
+
loop do
|
77
|
+
begin
|
78
|
+
(our[:work_done] = true) && break if work_done?
|
79
|
+
process job
|
80
|
+
sleep our[:frequency] if our[:frequency]
|
81
|
+
rescue => e
|
82
|
+
log_error e
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
our[:work_done] && work_done
|
87
|
+
errands :stop, :worker
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def stop(threads = nil)
|
92
|
+
our_selection(threads || our[:threads]) do |n, t|
|
93
|
+
if Thread.current == t
|
94
|
+
errands :stop, n
|
95
|
+
else
|
96
|
+
t.exit
|
97
|
+
t.join
|
98
|
+
wait_for n, :status, false
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
our[:stopped] = !status.values.any? { |t| t.alive? }
|
103
|
+
end
|
104
|
+
|
105
|
+
def status
|
106
|
+
our_selection our[:threads]
|
107
|
+
end
|
108
|
+
|
109
|
+
def status
|
110
|
+
our_selection our[:threads]
|
111
|
+
end
|
112
|
+
|
113
|
+
def wait_for(key, meth = nil, result = true)
|
114
|
+
loop do
|
115
|
+
break if meth && our[key].respond_to?(meth) ?
|
116
|
+
our[key].send(meth) == result :
|
117
|
+
!!our[key] == result
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def work_done?
|
122
|
+
false
|
123
|
+
end
|
124
|
+
|
125
|
+
private
|
126
|
+
|
127
|
+
def our_selection(selection)
|
128
|
+
our.dup.select do |k, v|
|
129
|
+
Array(selection).include?(k).tap { |bool|
|
130
|
+
yield k, our[k] if bool && block_given?
|
131
|
+
}
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def errands(errand, *_)
|
136
|
+
name = thread_name(1).to_s << "_#{errand}"
|
137
|
+
|
138
|
+
running name.to_sym do
|
139
|
+
send errand, *_
|
140
|
+
our[:threads].delete my[:name]
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def running(name = nil, &block)
|
145
|
+
if @running_mode
|
146
|
+
send @running_mode, &block
|
147
|
+
else
|
148
|
+
register_thread name || thread_name, Thread.new(&block)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def thread_name(caller_depth = 2)
|
153
|
+
caller_locations(caller_depth, 1).first.base_label.dup.tap { |n|
|
154
|
+
n << "_" << Time.now.to_f.to_s.sub('.', '_') if n.end_with? 's'
|
155
|
+
}.to_sym
|
156
|
+
end
|
157
|
+
|
158
|
+
def register_thread(name, thread)
|
159
|
+
((our[:threads] ||= []) << name).uniq!
|
160
|
+
his our[name] = thread, :name, name
|
161
|
+
end
|
162
|
+
|
163
|
+
def secure_check(name, meth)
|
164
|
+
our[name] && our[name].respond_to?(meth) && our[name].send(meth)
|
165
|
+
end
|
166
|
+
|
167
|
+
def log_error(e)
|
168
|
+
puts e.message
|
169
|
+
end
|
170
|
+
|
171
|
+
def startup
|
172
|
+
{}
|
173
|
+
end
|
174
|
+
|
175
|
+
def work_done; end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
data/lib/errands.rb
ADDED
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: errands
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- lacravate
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-09-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.10.4
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.10.4
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: simplecov
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.15'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.15'
|
55
|
+
description: A code frame to have an orderly use of thread and separate runtime and
|
56
|
+
actual job of a Ruby class
|
57
|
+
email:
|
58
|
+
- lacravate@lacravate.fr
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- lib/errands.rb
|
64
|
+
- lib/errands/runner.rb
|
65
|
+
- lib/errands/version.rb
|
66
|
+
homepage: https://github.com/lacravate/errands
|
67
|
+
licenses: []
|
68
|
+
metadata: {}
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options: []
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
requirements: []
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 2.4.5
|
86
|
+
signing_key:
|
87
|
+
specification_version: 4
|
88
|
+
summary: Turn a model into a threaded service
|
89
|
+
test_files: []
|