Skip to content

Commit b371025

Browse files
Rename to async-service-supervisor.
1 parent 33487bb commit b371025

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1073
-1678
lines changed
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# frozen_string_literal: true
22

3-
require_relative "lib/async/container/supervisor/version"
3+
require_relative "lib/async/service/supervisor/version"
44

55
Gem::Specification.new do |spec|
6-
spec.name = "async-container-supervisor"
7-
spec.version = Async::Container::Supervisor::VERSION
6+
spec.name = "async-service-supervisor"
7+
spec.version = Async::Service::Supervisor::VERSION
88

99
spec.summary = "A supervisor for managing multiple container processes."
1010
spec.authors = ["Samuel Williams"]
@@ -13,18 +13,19 @@ Gem::Specification.new do |spec|
1313
spec.cert_chain = ["release.cert"]
1414
spec.signing_key = File.expand_path("~/.gem/release.pem")
1515

16-
spec.homepage = "https://github.com/socketry/async-container-supervisor"
16+
spec.homepage = "https://github.com/socketry/async-service-supervisor"
1717

1818
spec.metadata = {
19-
"documentation_uri" => "https://socketry.github.io/async-container-supervisor/",
20-
"source_code_uri" => "https://github.com/socketry/async-container-supervisor.git",
19+
"documentation_uri" => "https://socketry.github.io/async-service-supervisor/",
20+
"source_code_uri" => "https://github.com/socketry/async-service-supervisor.git",
2121
}
2222

2323
spec.files = Dir.glob(["{bake,context,lib}/**/*", "*.md"], File::FNM_DOTMATCH, base: __dir__)
2424

2525
spec.required_ruby_version = ">= 3.2"
2626

27-
spec.add_dependency "async-service"
27+
spec.add_dependency "async-bus"
28+
spec.add_dependency "async-service", "~> 0.15"
2829
spec.add_dependency "io-endpoint"
2930
spec.add_dependency "memory", "~> 0.7"
3031
spec.add_dependency "memory-leak", "~> 0.5"
Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,29 @@
66
def initialize(...)
77
super
88

9-
require "async/container/supervisor"
9+
require "async/service/supervisor"
1010
end
1111

1212
# Restart the container, typically causing it to exit (the parent process should then restart it).
1313
def restart
1414
client do |connection|
15-
connection.call(do: :restart)
15+
supervisor = connection[:supervisor]
16+
supervisor.restart
1617
end
1718
end
1819

1920
# Reload the services gracefully, allowing them to reconfigure without dropping connections.
2021
def reload
2122
client do |connection|
22-
connection.call(do: :restart, signal: :HUP)
23+
supervisor = connection[:supervisor]
24+
supervisor.restart(signal: :HUP)
2325
end
2426
end
2527

2628
def status
2729
client do |connection|
28-
connection.call(do: :status)
30+
supervisor = connection[:supervisor]
31+
supervisor.status
2932
end
3033
end
3134

@@ -35,27 +38,25 @@ def status
3538
# that are retained after garbage collection.
3639
#
3740
# @parameter duration [Integer] The duration in seconds to sample for (default: 10).
38-
# @parameter connection_id [String] The connection ID to target a specific worker.
41+
# @parameter connection_id [Integer] The connection ID to target a specific worker.
3942
def memory_sample(duration: 10, connection_id:)
4043
client do |connection|
4144
Console.info(self, "Sampling memory from worker...", duration: duration, connection_id: connection_id)
4245

43-
# Build the operation request:
44-
operation = {do: :memory_sample, duration: duration}
45-
46-
# Use the forward operation to proxy the request to a worker:
47-
return connection.call(do: :forward, operation: operation, connection_id: connection_id)
46+
supervisor = connection[:supervisor]
47+
worker = supervisor[connection_id]
48+
return worker.memory_sample(duration: duration)
4849
end
4950
end
5051

5152
private
5253

5354
def endpoint
54-
Async::Container::Supervisor.endpoint
55+
Async::Service::Supervisor.endpoint
5556
end
5657

5758
def client(&block)
5859
Sync do
59-
Async::Container::Supervisor::Client.new(endpoint: self.endpoint).connect(&block)
60+
Async::Service::Supervisor::Client.new(endpoint: self.endpoint).connect(&block)
6061
end
6162
end

context/getting-started.md

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
# Getting Started
22

3-
This guide explains how to get started with `async-container-supervisor` to supervise and monitor worker processes in your Ruby applications.
3+
This guide explains how to get started with `async-service-supervisor` to supervise and monitor worker processes in your Ruby applications.
44

55
## Installation
66

77
Add the gem to your project:
88

99
```bash
10-
$ bundle add async-container-supervisor
10+
$ bundle add async-service-supervisor
1111
```
1212

1313
## Core Concepts
1414

15-
`async-container-supervisor` provides a robust process supervision system built on top of {ruby Async::Service::Generic}. The key components are:
15+
`async-service-supervisor` provides a robust process supervision system built on top of {ruby Async::Service::Generic}. The key components are:
1616

17-
- {ruby Async::Container::Supervisor::Environment}: An environment mixin that sets up a supervisor service in your application.
18-
- {ruby Async::Container::Supervisor::Supervised}: An environment mixin that enables workers to connect to and be supervised by the supervisor.
19-
- {ruby Async::Container::Supervisor::Server}: The server that handles communication with workers and performs monitoring.
20-
- {ruby Async::Container::Supervisor::Worker}: A client that connects workers to the supervisor for health monitoring and diagnostics.
17+
- {ruby Async::Service::Supervisor::Environment}: An environment mixin that sets up a supervisor service in your application.
18+
- {ruby Async::Service::Supervisor::Supervised}: An environment mixin that enables workers to connect to and be supervised by the supervisor.
19+
- {ruby Async::Service::Supervisor::Server}: The server that handles communication with workers and performs monitoring.
20+
- {ruby Async::Service::Supervisor::Worker}: A client that connects workers to the supervisor for health monitoring and diagnostics.
2121

2222
### Process Architecture
2323

@@ -27,7 +27,7 @@ The supervisor operates as a multi-process architecture with three layers:
2727
graph TD
2828
Controller[Async::Container::Controller<br/>Root Process]
2929
30-
Controller -->|spawns & manages| Supervisor[Supervisor Process<br/>async-container-supervisor]
30+
Controller -->|spawns & manages| Supervisor[Supervisor Process<br/>async-service-supervisor]
3131
Controller -->|spawns & manages| Worker1[Worker Process 1]
3232
Controller -->|spawns & manages| Worker2[Worker Process 2]
3333
Controller -->|spawns & manages| WorkerN[Worker Process N...]
@@ -51,18 +51,19 @@ Create a service configuration file (e.g., `service.rb`):
5151
#!/usr/bin/env async-service
5252
# frozen_string_literal: true
5353

54-
require "async/container/supervisor"
54+
require "async/service/supervisor"
5555

5656
class MyWorkerService < Async::Service::Generic
5757
def setup(container)
5858
super
5959

6060
container.run(name: self.class.name, count: 4, restart: true) do |instance|
6161
Async do
62-
# Connect to the supervisor if available:
63-
if @environment.implements?(Async::Container::Supervisor::Supervised)
64-
@evaluator.make_supervised_worker(instance).run
65-
end
62+
# Get the environment evaluator:
63+
evaluator = self.environment.evaluator
64+
65+
# Prepare the instance (connects to supervisor if available):
66+
evaluator.prepare!(instance)
6667

6768
# Mark the worker as ready:
6869
instance.ready!
@@ -85,12 +86,12 @@ service "worker" do
8586
service_class MyWorkerService
8687

8788
# Enable supervision for this service:
88-
include Async::Container::Supervisor::Supervised
89+
include Async::Service::Supervisor::Supervised
8990
end
9091

9192
# Define the supervisor service:
9293
service "supervisor" do
93-
include Async::Container::Supervisor::Environment
94+
include Async::Service::Supervisor::Environment
9495
end
9596
```
9697

@@ -119,17 +120,17 @@ For example, to add monitoring:
119120

120121
```ruby
121122
service "supervisor" do
122-
include Async::Container::Supervisor::Environment
123+
include Async::Service::Supervisor::Environment
123124

124125
monitors do
125126
[
126127
# Log process metrics for observability:
127-
Async::Container::Supervisor::ProcessMonitor.new(
128+
Async::Service::Supervisor::ProcessMonitor.new(
128129
interval: 60
129130
),
130131

131132
# Restart workers exceeding memory limits:
132-
Async::Container::Supervisor::MemoryMonitor.new(
133+
Async::Service::Supervisor::MemoryMonitor.new(
133134
interval: 10,
134135
maximum_size_limit: 1024 * 1024 * 500 # 500MB limit per process
135136
)
@@ -138,7 +139,7 @@ service "supervisor" do
138139
end
139140
```
140141

141-
See the {ruby Async::Container::Supervisor::MemoryMonitor Memory Monitor} and {ruby Async::Container::Supervisor::ProcessMonitor Process Monitor} guides for detailed configuration options and best practices.
142+
See the {ruby Async::Service::Supervisor::MemoryMonitor Memory Monitor} and {ruby Async::Service::Supervisor::ProcessMonitor Process Monitor} guides for detailed configuration options and best practices.
142143

143144
### Collecting Diagnostics
144145

context/index.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33
---
44
description: A supervisor for managing multiple container processes.
55
metadata:
6-
documentation_uri: https://socketry.github.io/async-container-supervisor/
7-
source_code_uri: https://github.com/socketry/async-container-supervisor.git
6+
documentation_uri: https://socketry.github.io/async-service-supervisor/
7+
source_code_uri: https://github.com/socketry/async-service-supervisor.git
88
files:
99
- path: getting-started.md
1010
title: Getting Started
11-
description: This guide explains how to get started with `async-container-supervisor`
11+
description: This guide explains how to get started with `async-service-supervisor`
1212
to supervise and monitor worker processes in your Ruby applications.
1313
- path: memory-monitor.md
1414
title: Memory Monitor
15-
description: This guide explains how to use the <code class="language-ruby">Async::Container::Supervisor::MemoryMonitor</code>
15+
description: This guide explains how to use the <code class="language-ruby">Async::Service::Supervisor::MemoryMonitor</code>
1616
to detect and restart workers that exceed memory limits or develop memory leaks.
1717
- path: process-monitor.md
1818
title: Process Monitor
19-
description: This guide explains how to use the <code class="language-ruby">Async::Container::Supervisor::ProcessMonitor</code>
19+
description: This guide explains how to use the <code class="language-ruby">Async::Service::Supervisor::ProcessMonitor</code>
2020
to log CPU and memory metrics for your worker processes.

context/memory-monitor.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Memory Monitor
22

3-
This guide explains how to use the {ruby Async::Container::Supervisor::MemoryMonitor} to detect and restart workers that exceed memory limits or develop memory leaks.
3+
This guide explains how to use the {ruby Async::Service::Supervisor::MemoryMonitor} to detect and restart workers that exceed memory limits or develop memory leaks.
44

55
## Overview
66

@@ -21,11 +21,11 @@ Add a memory monitor to your supervisor service to automatically restart workers
2121

2222
```ruby
2323
service "supervisor" do
24-
include Async::Container::Supervisor::Environment
24+
include Async::Service::Supervisor::Environment
2525

2626
monitors do
2727
[
28-
Async::Container::Supervisor::MemoryMonitor.new(
28+
Async::Service::Supervisor::MemoryMonitor.new(
2929
# Check worker memory every 10 seconds:
3030
interval: 10,
3131

@@ -52,7 +52,7 @@ The `MemoryMonitor` accepts the following options:
5252
The interval (in seconds) at which to check for memory leaks. Default: `10` seconds.
5353

5454
```ruby
55-
Async::Container::Supervisor::MemoryMonitor.new(interval: 30)
55+
Async::Service::Supervisor::MemoryMonitor.new(interval: 30)
5656
```
5757

5858
### `maximum_size_limit`
@@ -61,10 +61,10 @@ The maximum memory size (in bytes) per process. When a process exceeds this limi
6161

6262
```ruby
6363
# 500MB limit
64-
Async::Container::Supervisor::MemoryMonitor.new(maximum_size_limit: 1024 * 1024 * 500)
64+
Async::Service::Supervisor::MemoryMonitor.new(maximum_size_limit: 1024 * 1024 * 500)
6565

6666
# 1GB limit
67-
Async::Container::Supervisor::MemoryMonitor.new(maximum_size_limit: 1024 * 1024 * 1024)
67+
Async::Service::Supervisor::MemoryMonitor.new(maximum_size_limit: 1024 * 1024 * 1024)
6868
```
6969

7070
### `total_size_limit`
@@ -73,7 +73,7 @@ The total size limit (in bytes) for all monitored processes combined. If not spe
7373

7474
```ruby
7575
# Total limit of 2GB across all workers
76-
Async::Container::Supervisor::MemoryMonitor.new(
76+
Async::Service::Supervisor::MemoryMonitor.new(
7777
maximum_size_limit: 1024 * 1024 * 500, # 500MB per process
7878
total_size_limit: 1024 * 1024 * 1024 * 2 # 2GB total
7979
)
@@ -87,15 +87,15 @@ Default: `{duration: 30, timeout: 120}`
8787

8888
```ruby
8989
# Customize memory sampling:
90-
Async::Container::Supervisor::MemoryMonitor.new(
90+
Async::Service::Supervisor::MemoryMonitor.new(
9191
memory_sample: {
9292
duration: 60, # Sample for 60 seconds
9393
timeout: 180 # Timeout after 180 seconds
9494
}
9595
)
9696

9797
# Disable memory sampling:
98-
Async::Container::Supervisor::MemoryMonitor.new(
98+
Async::Service::Supervisor::MemoryMonitor.new(
9999
memory_sample: nil
100100
)
101101
```

context/process-monitor.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Process Monitor
22

3-
This guide explains how to use the {ruby Async::Container::Supervisor::ProcessMonitor} to log CPU and memory metrics for your worker processes.
3+
This guide explains how to use the {ruby Async::Service::Supervisor::ProcessMonitor} to log CPU and memory metrics for your worker processes.
44

55
## Overview
66

@@ -16,20 +16,20 @@ Use the `ProcessMonitor` when you need:
1616
- **Debugging assistance**: Correlate resource usage with application behavior.
1717
- **Cost optimization**: Right-size infrastructure based on actual usage.
1818

19-
Unlike the {ruby Async::Container::Supervisor::MemoryMonitor}, which takes action when limits are exceeded, the `ProcessMonitor` is purely observational - it logs metrics without interfering with worker processes.
19+
Unlike the {ruby Async::Service::Supervisor::MemoryMonitor}, which takes action when limits are exceeded, the `ProcessMonitor` is purely observational - it logs metrics without interfering with worker processes.
2020

2121
## Usage
2222

2323
Add a process monitor to log resource usage every minute:
2424

2525
```ruby
2626
service "supervisor" do
27-
include Async::Container::Supervisor::Environment
27+
include Async::Service::Supervisor::Environment
2828

2929
monitors do
3030
[
3131
# Log CPU and memory metrics for all processes:
32-
Async::Container::Supervisor::ProcessMonitor.new(
32+
Async::Service::Supervisor::ProcessMonitor.new(
3333
interval: 60 # Capture metrics every minute
3434
)
3535
]
@@ -51,10 +51,10 @@ The interval (in seconds) at which to capture and log process metrics. Default:
5151

5252
```ruby
5353
# Log every 30 seconds
54-
Async::Container::Supervisor::ProcessMonitor.new(interval: 30)
54+
Async::Service::Supervisor::ProcessMonitor.new(interval: 30)
5555

5656
# Log every 5 minutes
57-
Async::Container::Supervisor::ProcessMonitor.new(interval: 300)
57+
Async::Service::Supervisor::ProcessMonitor.new(interval: 300)
5858
```
5959

6060
## Captured Metrics

examples/hang/service.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
44
# Released under the MIT License.
55
# Copyright, 2025, by Samuel Williams.
66

7-
require "async/container/supervisor"
7+
require "async/service/supervisor"
88

99
class SleepService < Async::Service::Generic
1010
def setup(container)
1111
super
1212

1313
container.run(name: self.class.name, count: 1, restart: true, health_check_timeout: 2) do |instance|
1414
Async do
15-
if @environment.implements?(Async::Container::Supervisor::Supervised)
16-
@evaluator.make_supervised_worker(instance).run
17-
end
15+
evaluator = self.environment.evaluator
16+
17+
evaluator.prepare!(instance)
1818

1919
start_time = Time.now
2020

@@ -31,9 +31,9 @@ def setup(container)
3131
service "sleep" do
3232
service_class SleepService
3333

34-
include Async::Container::Supervisor::Supervised
34+
include Async::Service::Supervisor::Supervised
3535
end
3636

3737
service "supervisor" do
38-
include Async::Container::Supervisor::Environment
38+
include Async::Service::Supervisor::Environment
3939
end

0 commit comments

Comments
 (0)