errands 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,3 @@
1
+ module Errands
2
+ VERSION = "0.0.1"
3
+ end
data/lib/errands.rb ADDED
@@ -0,0 +1,3 @@
1
+ $: << File.dirname(__FILE__)
2
+
3
+ require 'errands/runner'
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: []