Skip to content

Commit e557e7c

Browse files
Document child lifecycle APIs
Assisted-By: devx/a01026a8-dd63-4b91-bae4-aec7ee8f7fa3
1 parent 5108143 commit e557e7c

8 files changed

Lines changed: 76 additions & 0 deletions

File tree

lib/async/container/child.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,16 @@
1010

1111
module Async
1212
module Container
13+
# Represents a child execution unit managed by a container.
1314
class Child
1415
# The default amount of time to wait for a child to be reaped after its
1516
# notification channel closes.
1617
REAP_TIMEOUT = 1.0
1718

19+
# Initialize the child with the given notification channel.
20+
# @parameter channel [Channel] The channel used to receive child notifications.
21+
# @parameter name [String | Nil] The optional child name.
22+
# @parameter options [Hash] Additional child options.
1823
def initialize(channel, name: nil, **options)
1924
@channel = channel
2025
@name = name
@@ -73,6 +78,11 @@ def stop(graceful = true, &block)
7378
return status
7479
end
7580

81+
# Receive notification messages from the child until a message is available, the channel closes, or the timeout expires.
82+
# @parameter timeout [Numeric | Nil] The maximum time to wait for a message.
83+
# @yields {|message| ...} Each received notification message.
84+
# @parameter message [Hash] The notification message from the child.
85+
# @returns [Hash | Boolean | Nil] The message, `false` on timeout, or `nil` when the channel closes.
7686
def receive(timeout = nil, &block)
7787
deadline = Deadline.new(timeout) if timeout
7888

lib/async/container/forked.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,16 @@ module Async
1010
module Container
1111
# Public factory for multi-process containers.
1212
module Forked
13+
# Create a generic container which spawns forked children.
14+
# @parameter arguments [Array] Positional arguments for {Generic#initialize}.
15+
# @parameter options [Hash] Keyword options for {Generic#initialize}.
16+
# @returns [Generic] A generic container configured with {Forked::Child}.
1317
def self.new(*arguments, **options)
1418
Generic.new(Child, *arguments, **options)
1519
end
1620

21+
# Whether this container uses multiple processes.
22+
# @returns [Boolean]
1723
def self.multiprocess?
1824
true
1925
end

lib/async/container/forked/child.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,15 @@
99
module Async
1010
module Container
1111
module Forked
12+
# Represents a child process managed by a forked container.
1213
class Child < Container::Child
14+
# Start a child process using `fork`.
15+
# @parameter channel [Channel] The notification channel for the child.
16+
# @parameter name [String | Nil] The optional child name.
17+
# @parameter options [Hash] Additional child options.
18+
# @yields {|instance| ...} The child process body.
19+
# @parameter instance [Instance] The child-side instance interface.
20+
# @returns [Child] The forked child process.
1321
def self.call(channel: Channel.new, name: nil, **options, &block)
1422
process_id = ::Thread.new do
1523
::Process.fork do
@@ -39,6 +47,10 @@ def self.call(channel: Channel.new, name: nil, **options, &block)
3947
return self.new(process_id, channel, name: name, **options)
4048
end
4149

50+
# Initialize the child process wrapper.
51+
# @parameter process_id [Integer] The process identifier.
52+
# @parameter channel [Channel] The notification channel for the child.
53+
# @parameter options [Hash] Additional child options.
4254
def initialize(process_id, channel, **options)
4355
@process_id = process_id
4456
@status = nil
@@ -78,6 +90,9 @@ def restart!
7890
end
7991
end
8092

93+
# Reap the child process.
94+
# @parameter timeout [Numeric | Nil] The maximum time to wait for the process to exit.
95+
# @returns [::Process::Status | Nil] The process status, or `nil` if the timeout expired.
8196
def reap(timeout = nil)
8297
unless @status
8398
if timeout

lib/async/container/generic.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,18 @@ def self.processor_count(env = ENV)
3535
class Generic
3636
UNNAMED = "Unnamed"
3737

38+
# Create and run a generic container.
39+
# @parameter arguments [Array] Positional arguments for {#run}.
40+
# @parameter options [Hash] Keyword options for {#run}.
41+
# @returns [Generic] The running container.
3842
def self.run(...)
3943
self.new.run(...)
4044
end
4145

46+
# Initialize the generic container.
47+
# @parameter child_type [Class] The child type used to spawn children.
48+
# @parameter policy [Policy] The policy for managing child lifecycle events.
49+
# @parameter options [Hash] Additional group options.
4250
def initialize(child_type, policy: Policy::DEFAULT, **options)
4351
@child_type = child_type
4452
@group = Group.new(**options)

lib/async/container/group.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class Group
1919
# Emitted when a child exits the group.
2020
Exit = Data.define(:child, :status)
2121

22+
# Initialize the group.
2223
def initialize
2324
@children = Set.new
2425
@events = Thread::Queue.new

lib/async/container/hybrid.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,24 @@
88

99
module Async
1010
module Container
11+
# Represents a container which spawns forked processes that manage threaded children.
1112
class Hybrid < Generic
13+
# Initialize the hybrid container.
14+
# @parameter arguments [Array] Positional arguments for {Generic#initialize}.
15+
# @parameter options [Hash] Keyword options for {Generic#initialize}.
1216
def initialize(*arguments, **options)
1317
super(Forked::Child, *arguments, **options)
1418
end
1519

20+
# Spawn forked containers, each managing a set of threaded children.
21+
# @parameter count [Integer | Nil] The total number of threaded children.
22+
# @parameter forks [Integer | Nil] The number of forked child containers.
23+
# @parameter threads [Integer | Nil] The number of threads per fork.
24+
# @parameter health_check_timeout [Numeric | Nil] The timeout for child health checks.
25+
# @parameter options [Hash] Additional child options.
26+
# @yields {|instance| ...} The threaded child body.
27+
# @parameter instance [Threaded::Instance] The child-side instance interface.
28+
# @returns [Hybrid] The hybrid container.
1629
def run(count: nil, forks: nil, threads: nil, health_check_timeout: nil, **options, &block)
1730
processor_count = Async::Container.processor_count
1831
count ||= processor_count ** 2
@@ -42,6 +55,8 @@ def run(count: nil, forks: nil, threads: nil, health_check_timeout: nil, **optio
4255
return self
4356
end
4457

58+
# Whether this container uses multiple processes.
59+
# @returns [Boolean]
4560
def self.multiprocess?
4661
true
4762
end

lib/async/container/threaded.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,16 @@ module Async
1010
module Container
1111
# Public factory for multi-thread containers.
1212
module Threaded
13+
# Create a generic container which spawns threaded children.
14+
# @parameter arguments [Array] Positional arguments for {Generic#initialize}.
15+
# @parameter options [Hash] Keyword options for {Generic#initialize}.
16+
# @returns [Generic] A generic container configured with {Threaded::Child}.
1317
def self.new(*arguments, **options)
1418
Generic.new(Child, *arguments, **options)
1519
end
1620

21+
# Whether this container uses multiple processes.
22+
# @returns [Boolean]
1723
def self.multiprocess?
1824
false
1925
end

lib/async/container/threaded/child.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,15 @@
99
module Async
1010
module Container
1111
module Threaded
12+
# Represents a child thread managed by a threaded container.
1213
class Child < Container::Child
14+
# Start a child thread.
15+
# @parameter channel [Channel] The notification channel for the child.
16+
# @parameter name [String | Nil] The optional child name.
17+
# @parameter options [Hash] Additional child options.
18+
# @yields {|instance| ...} The child thread body.
19+
# @parameter instance [Instance] The child-side instance interface.
20+
# @returns [Child] The threaded child.
1321
def self.call(channel: Channel.new, name: nil, **options, &block)
1422
thread = ::Thread.new do
1523
begin
@@ -32,6 +40,10 @@ def self.call(channel: Channel.new, name: nil, **options, &block)
3240
return self.new(thread, channel, name: name, **options)
3341
end
3442

43+
# Initialize the child thread wrapper.
44+
# @parameter thread [Thread] The child thread.
45+
# @parameter channel [Channel] The notification channel for the child.
46+
# @parameter options [Hash] Additional child options.
3547
def initialize(thread, channel, **options)
3648
@thread = thread
3749
@status = nil
@@ -61,6 +73,9 @@ def restart!
6173
@thread.raise(Restart)
6274
end
6375

76+
# Reap the child thread.
77+
# @parameter timeout [Numeric | Nil] The maximum time to wait for the thread to exit.
78+
# @returns [Status | Nil] The thread status, or `nil` if the timeout expired.
6479
def reap(timeout = nil)
6580
if timeout
6681
return nil unless @thread.join(timeout)

0 commit comments

Comments
 (0)