main_loop 0.1.4.367214 → 0.1.4.369901
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/lib/main_loop/bus.rb +3 -3
- data/lib/main_loop/dispatcher.rb +3 -3
- data/lib/main_loop/handler.rb +0 -24
- data/lib/main_loop/process_handler.rb +3 -3
- data/lib/main_loop/thread_handler.rb +16 -7
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6715ecb631f944f513d3ef4083ca568fe7f1e50fda1e007ff27a08f9d11da959
|
|
4
|
+
data.tar.gz: f639291ab878bec54c493e79abf9e5bd004ab670c44dea5db0fc2d892baf2070
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ba62a2aa69a9774f8a6c851942689546ea6ab5a34297a60724c627fbb1427c5dde21d5f2435d6ade44afcec90de929c3066bd6f36439210bf0692af1becc83c5
|
|
7
|
+
data.tar.gz: a1892e24867d6be57ed7f00834f404635d92b907c46bcf1a5149559af84a5c05caa452cbdd0a41c2ca6e255bd8511c16160082fa0303a1ee9b12de344b12d104
|
data/lib/main_loop/bus.rb
CHANGED
|
@@ -108,11 +108,11 @@ module MainLoop
|
|
|
108
108
|
|
|
109
109
|
# == Блокирующее чтение события
|
|
110
110
|
#
|
|
111
|
-
# Блокирует до получения
|
|
111
|
+
# Блокирует до получения события или таймаута.
|
|
112
112
|
# Использует {Timeouter.loop} для ограничения времени ожидания.
|
|
113
113
|
#
|
|
114
114
|
# @param timeout [Numeric] таймаут ожидания в секундах
|
|
115
|
-
# @return [String|nil]
|
|
115
|
+
# @return [String|nil] прочитанное событие (без символа новой строки) или nil при таймауте
|
|
116
116
|
def gets(timeout)
|
|
117
117
|
Timeouter.loop(timeout) do |t|
|
|
118
118
|
line = gets_nonblock if wait_for_event(t.left)
|
|
@@ -120,7 +120,7 @@ module MainLoop
|
|
|
120
120
|
end
|
|
121
121
|
end
|
|
122
122
|
|
|
123
|
-
# == Неблокирующее чтение
|
|
123
|
+
# == Неблокирующее чтение строки
|
|
124
124
|
#
|
|
125
125
|
# Читает посимвольно до конца строки (EOL).
|
|
126
126
|
# Буферизует символы и возвращает полную строку.
|
data/lib/main_loop/dispatcher.rb
CHANGED
|
@@ -130,7 +130,7 @@ module MainLoop
|
|
|
130
130
|
|
|
131
131
|
# == Отправить сигнал аварийного завершения
|
|
132
132
|
#
|
|
133
|
-
# Устанавливает
|
|
133
|
+
# Устанавливает код выхода 3 и инициирует терминацию.
|
|
134
134
|
# Если уже терминация — ничего не делает.
|
|
135
135
|
def crash
|
|
136
136
|
@exit_code = 3
|
|
@@ -194,7 +194,7 @@ module MainLoop
|
|
|
194
194
|
# == Логировать статус
|
|
195
195
|
#
|
|
196
196
|
# Логирует текущее состояние обработчиков (DEBUG уровень).
|
|
197
|
-
# Формат: "Total:N Running:M
|
|
197
|
+
# Формат: "Total:N Running:M Finished:K. Success:[] TERM"
|
|
198
198
|
#
|
|
199
199
|
# :nocov:
|
|
200
200
|
def log_status
|
|
@@ -202,7 +202,7 @@ module MainLoop
|
|
|
202
202
|
running = handlers.count(&:running?)
|
|
203
203
|
finihsed = handlers.count(&:finished?)
|
|
204
204
|
term_text = terminating? ? 'TERM' : ''
|
|
205
|
-
logger.debug("Total:#{total} Running:#{running}
|
|
205
|
+
logger.debug("Total:#{total} Running:#{running} Finished:#{finihsed} Success:#{handlers.map {|h| h.success?}.to_s}. #{term_text}".strip)
|
|
206
206
|
end
|
|
207
207
|
# :nocov:
|
|
208
208
|
end
|
data/lib/main_loop/handler.rb
CHANGED
|
@@ -18,30 +18,6 @@ require 'logger'
|
|
|
18
18
|
# - {#kill} — принудительное завершение
|
|
19
19
|
# - {#reap(status)} — обработка завершения процесса/потока
|
|
20
20
|
#
|
|
21
|
-
# == Пример использования
|
|
22
|
-
#
|
|
23
|
-
# class MyHandler < MainLoop::Handler
|
|
24
|
-
# def id
|
|
25
|
-
# @process_id
|
|
26
|
-
# end
|
|
27
|
-
#
|
|
28
|
-
# def term
|
|
29
|
-
# Process.kill('TERM', @process_id)
|
|
30
|
-
# end
|
|
31
|
-
#
|
|
32
|
-
# def run
|
|
33
|
-
# @process_id = Process.fork { yield }
|
|
34
|
-
# end
|
|
35
|
-
#
|
|
36
|
-
# def kill
|
|
37
|
-
# Process.kill('KILL', @process_id)
|
|
38
|
-
# end
|
|
39
|
-
#
|
|
40
|
-
# def reap(status)
|
|
41
|
-
# # обработка завершения
|
|
42
|
-
# end
|
|
43
|
-
# end
|
|
44
|
-
#
|
|
45
21
|
# == См. также
|
|
46
22
|
# - {MainLoop::ProcessHandler} — реализация для процессов
|
|
47
23
|
# - {MainLoop::ThreadHandler} — реализация для потоков
|
|
@@ -92,7 +92,7 @@ module MainLoop
|
|
|
92
92
|
def term(*_args)
|
|
93
93
|
unless @pid
|
|
94
94
|
@terminating_at ||= Time.now
|
|
95
|
-
logger.debug "Process[#{name}]
|
|
95
|
+
logger.debug "Process[#{name}] already terminated. Skipped."
|
|
96
96
|
return
|
|
97
97
|
end
|
|
98
98
|
|
|
@@ -116,7 +116,7 @@ module MainLoop
|
|
|
116
116
|
# @param *_args (Unused)
|
|
117
117
|
def kill(*_args)
|
|
118
118
|
unless @pid
|
|
119
|
-
logger.debug "Process[#{name}]
|
|
119
|
+
logger.debug "Process[#{name}] already Killed. Skipped."
|
|
120
120
|
return
|
|
121
121
|
end
|
|
122
122
|
|
|
@@ -142,7 +142,7 @@ module MainLoop
|
|
|
142
142
|
#
|
|
143
143
|
# Создает дочерний процесс и настраивает обработку ошибок.
|
|
144
144
|
#
|
|
145
|
-
# @yield
|
|
145
|
+
# @yield выполнить блок кода в дочернем процессе
|
|
146
146
|
# @return [Integer] PID дочернего процесса
|
|
147
147
|
protected
|
|
148
148
|
|
|
@@ -7,8 +7,13 @@ require 'main_loop/handler'
|
|
|
7
7
|
# == Особенности потоков
|
|
8
8
|
#
|
|
9
9
|
# - Потоки не имеют status завершения (как процессы)
|
|
10
|
-
# -
|
|
11
|
-
# -
|
|
10
|
+
# - Если завершение graceful term, то @success отражает, завершился ли он после вызова on_term (true) или после нашего kill
|
|
11
|
+
# - Внутри on_term поток может быть завершен так, как считает нужным разработчик метода, например
|
|
12
|
+
# @stopped = true
|
|
13
|
+
# @thread&.wakeup
|
|
14
|
+
# @thread&.kill unless @thread&.join(2)
|
|
15
|
+
# - Если поток завершился сам, то смотрим на Thread.current[:exit_reason]
|
|
16
|
+
# - Завершение потока публикуется в ensure блоке и обрабатывается в MainLoop#start_loop_forever
|
|
12
17
|
#
|
|
13
18
|
# == Сигналы для потока
|
|
14
19
|
#
|
|
@@ -69,12 +74,13 @@ module MainLoop
|
|
|
69
74
|
# @param status [String] статус завершения (описание)
|
|
70
75
|
def reap(status)
|
|
71
76
|
logger.info "Thread[#{name}] exited: thread:#{@thread} Status:#{status}"
|
|
77
|
+
exit_reason = @thread[:exit_reason] if @thread
|
|
72
78
|
@thread = nil
|
|
73
79
|
@finished = true
|
|
74
80
|
|
|
75
81
|
return if terminating?
|
|
76
|
-
@success = false
|
|
77
82
|
|
|
83
|
+
@success = (exit_reason == :normal)
|
|
78
84
|
handle_retry
|
|
79
85
|
end
|
|
80
86
|
|
|
@@ -84,7 +90,7 @@ module MainLoop
|
|
|
84
90
|
def term(*_args)
|
|
85
91
|
unless @thread
|
|
86
92
|
@terminating_at ||= Time.now
|
|
87
|
-
logger.debug "Thread[#{name}]
|
|
93
|
+
logger.debug "Thread[#{name}] already terminated. Skipped."
|
|
88
94
|
return
|
|
89
95
|
end
|
|
90
96
|
|
|
@@ -107,7 +113,7 @@ module MainLoop
|
|
|
107
113
|
# @param *_args (Unused)
|
|
108
114
|
def kill(*_args)
|
|
109
115
|
unless @thread
|
|
110
|
-
logger.debug "Thread[#{name}]
|
|
116
|
+
logger.debug "Thread[#{name}] already Killed. Skipped."
|
|
111
117
|
return
|
|
112
118
|
end
|
|
113
119
|
|
|
@@ -133,20 +139,23 @@ module MainLoop
|
|
|
133
139
|
#
|
|
134
140
|
# Создает новый поток и настраивает обработку ошибок и завершения.
|
|
135
141
|
#
|
|
136
|
-
# @yield
|
|
142
|
+
# @yield выполнить блок кода в потоке
|
|
137
143
|
# @return [Thread] созданный поток
|
|
138
144
|
protected
|
|
139
145
|
|
|
140
146
|
def start_thread
|
|
141
147
|
@thread = Thread.new do
|
|
142
148
|
yield(self)
|
|
149
|
+
Thread.current[:exit_reason] = :normal
|
|
143
150
|
rescue StandardError => e
|
|
151
|
+
Thread.current[:exit_reason] = :exception
|
|
144
152
|
logger.error "Thread[#{name}] crashed: #{e.message}"
|
|
145
153
|
ensure
|
|
154
|
+
Thread.current[:exit_reason] ||= :killed
|
|
146
155
|
publish("reap:#{id}:exited")
|
|
147
156
|
end
|
|
148
157
|
@finished = false
|
|
149
158
|
logger.info "Thread[#{name}] created: thread:#{@thread}"
|
|
150
|
-
|
|
159
|
+
end
|
|
151
160
|
end
|
|
152
161
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: main_loop
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.4.
|
|
4
|
+
version: 0.1.4.369901
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Samoilenko Yuri
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-04-
|
|
11
|
+
date: 2026-04-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|