Skip to content

Commit f60b657

Browse files
committed
extending abstracts for the docs, adding curation for more types
1 parent b402936 commit f60b657

16 files changed

+86
-30
lines changed

Sources/ServiceLifecycle/AsyncCancelOnGracefulShutdownSequence.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ extension AsyncSequence where Self: Sendable, Element: Sendable {
2424
}
2525
}
2626

27-
/// An asynchronous sequence that is cancelled once graceful shutdown has triggered.
27+
/// An asynchronous sequence that is cancelled after graceful shutdown has triggered.
2828
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
2929
public struct AsyncCancelOnGracefulShutdownSequence<Base: AsyncSequence & Sendable>: AsyncSequence, Sendable
3030
where Base.Element: Sendable {
@@ -40,24 +40,29 @@ where Base.Element: Sendable {
4040
AsyncMapSequence<AsyncMapNilSequence<AsyncGracefulShutdownSequence>, _ElementOrGracefulShutdown>
4141
>
4242

43+
/// The type that the sequence produces.
4344
public typealias Element = Base.Element
4445

4546
@usableFromInline
4647
let _merge: Merged
4748

49+
/// Creates a new asynchronous sequence that cancels after graceful shutdown is triggered.
50+
/// - Parameter base: The asynchronous sequence to wrap.
4851
@inlinable
4952
public init(base: Base) {
5053
self._merge = merge(
5154
base.mapNil().map { .base($0) },
5255
AsyncGracefulShutdownSequence().mapNil().map { _ in .gracefulShutdown }
5356
)
5457
}
55-
58+
59+
/// Creates an iterator for the sequence.
5660
@inlinable
5761
public func makeAsyncIterator() -> AsyncIterator {
5862
AsyncIterator(iterator: self._merge.makeAsyncIterator())
5963
}
60-
64+
65+
/// An iterator for an asynchronous sequence that cancels after graceful shutdown is triggered.
6166
public struct AsyncIterator: AsyncIteratorProtocol {
6267
@usableFromInline
6368
var _iterator: Merged.AsyncIterator
@@ -69,7 +74,8 @@ where Base.Element: Sendable {
6974
init(iterator: Merged.AsyncIterator) {
7075
self._iterator = iterator
7176
}
72-
77+
78+
/// Returns the next item in the sequence, or `nil` if the sequence is finished.
7379
@inlinable
7480
public mutating func next() async rethrows -> Element? {
7581
guard !self._isFinished else {

Sources/ServiceLifecycle/AsyncGracefulShutdownSequence.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
/// An async sequence that emits an element once graceful shutdown has been triggered.
1616
///
17-
/// This sequence is a broadcast async sequence and will only produce one value and then finish.
17+
/// This sequence is a broadcast async sequence and only produces one value and then finishes.
1818
///
1919
/// - Note: This sequence respects cancellation and thus is `throwing`.
2020
@usableFromInline

Sources/ServiceLifecycle/Docs.docc/How to adopt ServiceLifecycle in applications.md renamed to Sources/ServiceLifecycle/Docs.docc/Adopting ServiceLifecycle in applications.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
# How to adopt ServiceLifecycle in applications
1+
# Adopting ServiceLifecycle in applications
22

33
Service Lifecycle provides a unified API for services to streamline their
4-
orchestration in applications: the ServiceGroup actor.
4+
orchestration in applications: the Service Group actor.
55

6-
## Why do we need this?
6+
## Overview
77

88
Applications often rely on fundamental observability services like logging and
99
metrics, while long-running actors bundle the application's business logic in
@@ -13,24 +13,24 @@ orchestrate the various services during startup and shutdown.
1313

1414
With the introduction of Structured Concurrency in Swift, multiple asynchronous
1515
services can be run concurrently with task groups. However, Structured
16-
Concurrency doesn't enforce consistent interfaces between the services, and it
17-
becomes hard to orchestrate them. To solve this issue, ``ServiceLifecycle``
16+
Concurrency doesn't enforce consistent interfaces between services, and it can
17+
become hard to orchestrate them. To solve this issue, ``ServiceLifecycle``
1818
provides the ``Service`` protocol to enforce a common API, as well as the
1919
``ServiceGroup`` actor to orchestrate all services in an application.
2020

2121
## Adopting the ServiceGroup actor in your application
2222

2323
This article focuses on how ``ServiceGroup`` works, and how you can adopt it in
2424
your application. If you are interested in how to properly implement a service,
25-
go check out the article: <doc:How-to-adopt-ServiceLifecycle-in-libraries>.
25+
go check out the article: <doc:Adopting-ServiceLifecycle-in-libraries>.
2626

2727
### How does the ServiceGroup actor work?
2828

2929
Under the hood, the ``ServiceGroup`` actor is just a complicated task group that
3030
runs each service in a separate child task, and handles individual services
3131
exiting or throwing. It also introduces the concept of graceful shutdown, which
3232
allows the safe teardown of all services in reverse order. Graceful shutdown is
33-
often used in server scenarios, i.e., when rolling out a new version and
33+
often used in server scenarios, for example when rolling out a new version and
3434
draining traffic from the old version (commonly referred to as quiescing).
3535

3636
### How to use ServiceGroup?

Sources/ServiceLifecycle/Docs.docc/How to adopt ServiceLifecycle in libraries.md renamed to Sources/ServiceLifecycle/Docs.docc/Adopting ServiceLifecycle in libraries.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
1-
# How to adopt ServiceLifecycle in libraries
1+
# Adopting ServiceLifecycle in libraries
22

33
Adopt the Service protocol for your service to allow a Service Group to coordinate it's operation with other services.
44

5-
Service Lifecycle provides a unified API to represent a long running task: the Service protocol.
5+
## Overview
66

7-
## Why do we need this?
7+
Service Lifecycle provides a unified API to represent a long running task: the ``Service`` protocol.
88

99
Before diving into how to adopt this protocol in your library, let's take a step back and talk about why we need to have this unified API.
1010
Services often need to schedule long-running tasks, such as sending keep-alive pings in the background, or the handling of incoming work like new TCP connections.
1111
Before Swift Concurrency was introduced, services put their work into separate threads using a `DispatchQueue` or an NIO `EventLoop`.
1212
Services often required explicit lifetime management to make sure their resources, such as threads, were shut down correctly.
13+
1314
With the introduction of Swift Concurrency, specifically by using Structured Concurrency, we have better tools to structure our programs and model our work as a tree of tasks.
14-
The ``Service`` protocol provides a common interface, a single `run()` method, for services to use when they run their long-running work.
15+
The `Service` protocol provides a common interface, a single `run()` method, for services to use when they run their long-running work.
1516
If all services in an application conform to this protocol, then orchestrating them becomes trivial.
1617

1718
## Adopting the Service protocol in your service
1819

19-
Adopting the ``Service`` protocol is quite easy.
20+
Adopting the `Service` protocol is quite easy.
2021
The protocol's single requirement is the ``Service/run()`` method.
2122
Make sure that your service adheres to the important caveats addressed in the following sections.
2223

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# ``ServiceLifecycle/AsyncCancelOnGracefulShutdownSequence``
2+
3+
## Topics
4+
5+
### Creating a cancelling sequence
6+
7+
- ``init(base:)``
8+
9+
### Iterating the sequence
10+
11+
- ``Element``
12+
- ``makeAsyncIterator()``
13+
- ``AsyncIterator``

Sources/ServiceLifecycle/Docs.docc/LoggingConfiguration.md renamed to Sources/ServiceLifecycle/Docs.docc/curation/LoggingConfiguration.md

File renamed without changes.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# ``ServiceLifecycle/Service``
2+
3+
## Topics
4+
5+
### Running a service
6+
7+
- ``run()``

Sources/ServiceLifecycle/Docs.docc/ServiceConfiguration.md renamed to Sources/ServiceLifecycle/Docs.docc/curation/ServiceConfiguration.md

File renamed without changes.

Sources/ServiceLifecycle/Docs.docc/ServiceGroup.md renamed to Sources/ServiceLifecycle/Docs.docc/curation/ServiceGroup.md

File renamed without changes.

Sources/ServiceLifecycle/Docs.docc/ServiceGroupConfiguration.md renamed to Sources/ServiceLifecycle/Docs.docc/curation/ServiceGroupConfiguration.md

File renamed without changes.

0 commit comments

Comments
 (0)