|
4 | 4 | # Copyright, 2025, by Samuel Williams. |
5 | 5 |
|
6 | 6 | require_relative "periodic_monitor" |
7 | | -require "memory/leaks/cluster" |
| 7 | +require "memory/leak/cluster" |
8 | 8 |
|
9 | 9 | module Async |
10 | 10 | module Container |
11 | 11 | module Supervisor |
12 | 12 | module Monitor |
13 | | - class MemoryMonitor < PeriodicMonitor |
14 | | - def initialize(cluster, **options) |
15 | | - super(**options) |
16 | | - @cluster = cluster |
17 | | - @processes = Hash.new |
| 13 | + class MemoryMonitor |
| 14 | + def initialize(interval: 10, limit: nil) |
| 15 | + @interval = interval |
| 16 | + @cluster = Memory::Leak::Cluster.new(limit: limit) |
| 17 | + @processes = Hash.new(0) |
18 | 18 | end |
19 | 19 |
|
20 | | - def register(wrapper, message) |
21 | | - if process_id = message[:process_id] |
| 20 | + def register(wrapper, registration) |
| 21 | + return unless instance = registration[:instance] |
| 22 | + |
| 23 | + Console.info(self, "Registering process:", instance) |
| 24 | + if process_id = instance[:process_id] |
22 | 25 | if @processes.key?(process_id) |
| 26 | + Console.info(self, "Incrementing process:", process_id: process_id) |
23 | 27 | @processes[process_id] += 1 |
24 | 28 | else |
| 29 | + Console.info(self, "Registering process:", process_id: process_id) |
25 | 30 | @cluster.add(process_id) |
26 | 31 | @processes[process_id] = 1 |
27 | 32 | end |
28 | 33 | end |
29 | 34 | end |
30 | 35 |
|
31 | | - def remove() |
32 | | - # if |
33 | | - @cluster.remove(worker.process_id) |
34 | | - end |
35 | | - |
36 | | - def call |
37 | | - @cluster.check! do |pid, monitor| |
38 | | - kill(pid) |
| 36 | + def remove(wrapper, registration) |
| 37 | + return unless instance = registration[:instance] |
| 38 | + |
| 39 | + if process_id = instance[:process_id] |
| 40 | + if @processes.key?(process_id) |
| 41 | + @processes[process_id] -= 1 |
| 42 | + |
| 43 | + if @processes[process_id] == 0 |
| 44 | + Console.info(self, "Deregistering process:", process_id: process_id) |
| 45 | + @cluster.remove(process_id) |
| 46 | + @processes.delete(process_id) |
| 47 | + end |
| 48 | + end |
39 | 49 | end |
40 | 50 | end |
41 | 51 |
|
42 | 52 | def run |
43 | | - while true |
44 | | - self.call |
45 | | - |
46 | | - sleep(@interval) |
| 53 | + Async do |
| 54 | + while true |
| 55 | + Console.info(self, "Checking for memory leaks...", processes: @processes) |
| 56 | + @cluster.check! do |process_id, monitor| |
| 57 | + Console.error(self, "Memory leak detected in process:", process_id: process_id, monitor: monitor) |
| 58 | + ::Process.kill(:INT, process_id) |
| 59 | + end |
| 60 | + |
| 61 | + sleep(@interval) |
| 62 | + end |
47 | 63 | end |
48 | 64 | end |
49 | 65 | end |
|
0 commit comments