Skip to content

remove closure variants to reduce API confusion #46

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 21 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ let lifecycle = ServiceLifecycle()
let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount)
lifecycle.registerShutdown(
label: "eventLoopGroup",
eventLoopGroup.syncShutdownGracefully
.sync(eventLoopGroup.syncShutdownGracefully)
)

// register another resource that should be started when the application starts
Expand Down Expand Up @@ -93,27 +93,24 @@ In larger Applications (Services) `ComponentLifecycle` can be used to manage the

### Registering items

`ServiceLifecycle` and `ComponentLifecycle` are containers for `LifecycleTask`s which need to be registered via one of the following variants:
`ServiceLifecycle` and `ComponentLifecycle` are containers for `LifecycleTask`s which need to be registered using a `LifecycleHandler` - a container for synchronous or asynchronous closures.

You can register simple blocking throwing handlers using:
Synchronous handlers are defined as `() throws -> Void`.

```swift
func register(label: String, start: @escaping () throws -> Void, shutdown: @escaping () throws -> Void)

func registerShutdown(label: String, _ handler: @escaping () throws -> Void)
```
Asynchronous handlers defined are as `(@escaping (Error?) -> Void) -> Void`.

or, you can register asynchronous and more complex handlers using:
`LifecycleHandler` comes with static helpers named `async` and `sync` designed to help simplify the registration call to:

```swift
func register(label: String, start: Handler, shutdown: Handler)

func registerShutdown(label: String, _ handler: Handler)
let foo = ...
lifecycle.register(
label: "foo",
start: .sync(foo.syncStart),
shutdown: .sync(foo.syncShutdown)
)
```

where `LifecycleHandler` is a container for an asynchronous closure defined as `(@escaping (Error?) -> Void) -> Void`

`LifecycleHandler` comes with static helpers named `async` and `sync` designed to help simplify the registration call to:
Or the async version:

```swift
let foo = ...
Expand All @@ -130,10 +127,18 @@ or, just shutdown:
let foo = ...
lifecycle.registerShutdown(
label: "foo",
.async(foo.asyncShutdown)
.sync(foo.syncShutdown)
)
```
Or the async version:

```swift
let foo = ...
lifecycle.registerShutdown(
label: "foo",
.async(foo.asyncShutdown)
)
```

you can also register a collection of `LifecycleTask`s (less typical) using:

Expand Down
38 changes: 0 additions & 38 deletions Sources/Lifecycle/Lifecycle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -218,25 +218,6 @@ public extension ServiceLifecycle {
func registerShutdown(label: String, _ handler: LifecycleHandler) {
self.lifecycle.registerShutdown(label: label, handler)
}

/// Adds a `Task` to a `Tasks` collection.
///
/// - parameters:
/// - label: label of the item, useful for debugging.
/// - start: closure to perform the shutdown.
/// - shutdown: closure to perform the shutdown.
func register(label: String, start: @escaping () throws -> Void, shutdown: @escaping () throws -> Void) {
self.lifecycle.register(label: label, start: start, shutdown: shutdown)
}

/// Adds a `Task` to a `Tasks` collection.
///
/// - parameters:
/// - label: label of the item, useful for debugging.
/// - handler: closure to perform the shutdown.
func registerShutdown(label: String, _ handler: @escaping () throws -> Void) {
self.lifecycle.registerShutdown(label: label, handler)
}
}

extension ServiceLifecycle {
Expand Down Expand Up @@ -538,23 +519,4 @@ public extension ComponentLifecycle {
func registerShutdown(label: String, _ handler: LifecycleHandler) {
self.register(label: label, start: .none, shutdown: handler)
}

/// Adds a `Task` to a `Tasks` collection.
///
/// - parameters:
/// - label: label of the item, useful for debugging.
/// - start: closure to perform the shutdown.
/// - shutdown: closure to perform the shutdown.
func register(label: String, start: @escaping () throws -> Void, shutdown: @escaping () throws -> Void) {
self.register(label: label, start: .sync(start), shutdown: .sync(shutdown))
}

/// Adds a `Task` to a `Tasks` collection.
///
/// - parameters:
/// - label: label of the item, useful for debugging.
/// - handler: closure to perform the shutdown.
func registerShutdown(label: String, _ handler: @escaping () throws -> Void) {
self.register(label: label, start: .none, shutdown: .sync(handler))
}
}
20 changes: 10 additions & 10 deletions Tests/LifecycleTests/ComponentLifecycleTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -199,22 +199,22 @@ final class ComponentLifecycleTests: XCTestCase {
do {
let id = UUID().uuidString
lifecycle.register(label: id,
start: {
start: .sync {
startCalls.append(id)
blockStartSemaphore.wait()
},
shutdown: {
shutdown: .sync {
XCTAssertTrue(startCalls.contains(id))
stopCalls.append(id)
})
}
do {
let id = UUID().uuidString
lifecycle.register(label: id,
start: {
start: .sync {
startCalls.append(id)
},
shutdown: {
shutdown: .sync {
XCTAssertTrue(startCalls.contains(id))
stopCalls.append(id)
})
Expand Down Expand Up @@ -416,7 +416,7 @@ final class ComponentLifecycleTests: XCTestCase {
let lifecycle = ComponentLifecycle(label: "test")
let items = (5 ... Int.random(in: 10 ... 20)).map { _ in Sync() }
items.forEach { item in
lifecycle.register(label: item.id, start: item.start, shutdown: item.shutdown)
lifecycle.register(label: item.id, start: .sync(item.start), shutdown: .sync(item.shutdown))
}

lifecycle.start { error in
Expand All @@ -435,8 +435,8 @@ final class ComponentLifecycleTests: XCTestCase {
lifecycle.register(label: "item1", start: .eventLoopFuture(item1.start), shutdown: .eventLoopFuture(item1.shutdown))

lifecycle.register(label: "blocker",
start: { () -> Void in try eventLoopGroup.next().makeSucceededFuture(()).wait() },
shutdown: { () -> Void in try eventLoopGroup.next().makeSucceededFuture(()).wait() })
start: .sync { try eventLoopGroup.next().makeSucceededFuture(()).wait() },
shutdown: .sync { try eventLoopGroup.next().makeSucceededFuture(()).wait() })

let item2 = NIOItem(eventLoopGroup: eventLoopGroup)
lifecycle.register(label: "item2", start: .eventLoopFuture(item2.start), shutdown: .eventLoopFuture(item2.shutdown))
Expand Down Expand Up @@ -493,8 +493,8 @@ final class ComponentLifecycleTests: XCTestCase {

let item = Sync()
lifecycle.register(label: "test",
start: item.start,
shutdown: item.shutdown)
start: .sync(item.start),
shutdown: .sync(item.shutdown))

lifecycle.start { error in
XCTAssertNil(error, "not expecting error")
Expand Down Expand Up @@ -526,7 +526,7 @@ final class ComponentLifecycleTests: XCTestCase {
let lifecycle = ComponentLifecycle(label: "test")

let item = Sync()
lifecycle.registerShutdown(label: "test", item.shutdown)
lifecycle.registerShutdown(label: "test", .sync(item.shutdown))

lifecycle.start { error in
XCTAssertNil(error, "not expecting error")
Expand Down