Skip to content

Commit 32ad34d

Browse files
committed
+cluster change joined -> up awaitable func, and minor cleanups
1 parent 194de5d commit 32ad34d

File tree

6 files changed

+42
-7
lines changed

6 files changed

+42
-7
lines changed

Sources/DistributedCluster/Cluster/Cluster+Membership.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,7 @@ extension Cluster {
703703
case notFoundAny(Cluster.Endpoint, in: Cluster.Membership)
704704
case atLeastStatusRequirementNotMet(expectedAtLeast: Cluster.MemberStatus, found: Cluster.Member)
705705
case statusRequirementNotMet(expected: Cluster.MemberStatus, found: Cluster.Member)
706+
case countRequirementNotMet(expected: Int, expectedStatus: Cluster.MemberStatus)
706707
case awaitStatusTimedOut(Duration, Error?)
707708

708709
var prettyDescription: String {
@@ -721,6 +722,8 @@ extension Cluster {
721722
return "Expected \(reflecting: foundMember.node) to be seen as at-least [\(expectedAtLeastStatus)] but was [\(foundMember.status)]"
722723
case .statusRequirementNotMet(let expectedStatus, let foundMember):
723724
return "Expected \(reflecting: foundMember.node) to be seen as [\(expectedStatus)] but was [\(foundMember.status)]"
725+
case .countRequirementNotMet(let count, let expectedStatus):
726+
return "Expected \(count) nodes to be seen as [\(expectedStatus)], but did not find enough"
724727
case .awaitStatusTimedOut(let duration, let lastError):
725728
let lastErrorMessage: String
726729
if let error = lastError {

Sources/DistributedCluster/Cluster/ClusterControl.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,23 @@ public struct ClusterControl {
162162
///
163163
/// - Returns `Cluster.Member` for the joined node.
164164
@discardableResult
165+
@available(*, deprecated, renamed: "up(within:)")
165166
public func joined(within: Duration) async throws -> Cluster.Member {
166167
try await self.waitFor(self.node, .up, within: within)
167168
}
168169

170+
/// Wait, within the given duration, until this actor system has joined the cluster and become ``Cluster/MemberStatus/up``.
171+
///
172+
/// - Parameters
173+
/// - node: The node to be joined by this system.
174+
/// - within: Duration to wait for.
175+
///
176+
/// - Returns `Cluster.Member` for the joined node.
177+
@discardableResult
178+
public func up(within: Duration) async throws -> Cluster.Member {
179+
try await self.waitFor(self.node, .up, within: within)
180+
}
181+
169182
/// Wait, within the given duration, until the passed in node has joined the cluster and become ``Cluster/MemberStatus/up``.
170183
///
171184
/// - Parameters
@@ -208,6 +221,22 @@ public struct ClusterControl {
208221
}
209222
}
210223

224+
/// Wait, within the given duration, for the cluster to have at least `nodes` members of the specified status.
225+
///
226+
/// - Parameters
227+
/// - nodes: The _least_ (inclusive) number of nodes (including this node) to be part of the cluster membership
228+
/// - status: The expected member status.
229+
/// - within: Duration to wait for.
230+
public func waitFor(countAtLeast: Int, _ status: Cluster.MemberStatus, within: Duration) async throws {
231+
try await self.waitForMembershipEventually(within: within) { membership in
232+
if membership.count(withStatus: status) >= countAtLeast {
233+
return membership
234+
} else {
235+
throw Cluster.MembershipError(.countRequirementNotMet(expected: countAtLeast, expectedStatus: status))
236+
}
237+
}
238+
}
239+
211240
/// Wait, within the given duration, for this actor system to be a member of all the nodes' respective cluster and have **at least** the specified status.
212241
///
213242
/// - Parameters

Sources/DistributedCluster/Cluster/Reception/OperationLogDistributedReceptionist.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -525,9 +525,9 @@ extension OpLogDistributedReceptionist {
525525

526526
for registration in registrations {
527527
if subscription.tryOffer(registration: registration) {
528-
self.log.notice("OFFERED \(registration.actorID) TO \(subscription)")
528+
self.log.trace("Offered \(registration.actorID) to \(subscription)")
529529
} else {
530-
self.log.notice("DROPPED \(registration.actorID) TO \(subscription)")
530+
self.log.trace("Dropped \(registration.actorID) to \(subscription)")
531531
}
532532
}
533533
}

Sources/DistributedCluster/ClusterSystem.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,7 +1153,7 @@ extension ClusterSystem {
11531153
let baggage = Baggage.current ?? .topLevel
11541154
// TODO: we can enrich this with actor and system information here if not already present.
11551155

1156-
return try await InstrumentationSystem.tracer.withSpan("\(target)", baggage: baggage, ofKind: .client) { span in
1156+
return try await InstrumentationSystem.tracer.withSpan("\(target)", baggage: baggage, ofKind: .client) { _ in
11571157
let reply: RemoteCallReply<Res> = try await self.withCallID(on: actor.id, target: target) { callID in
11581158
var invocation = InvocationMessage(
11591159
callID: callID,
@@ -1226,7 +1226,7 @@ extension ClusterSystem {
12261226
let baggage = Baggage.current ?? .topLevel
12271227
// TODO: we can enrich this with actor and system information here if not already present.
12281228

1229-
return try await InstrumentationSystem.tracer.withSpan("\(target)", baggage: baggage, ofKind: .client) { span in
1229+
return try await InstrumentationSystem.tracer.withSpan("\(target)", baggage: baggage, ofKind: .client) { _ in
12301230
let reply: RemoteCallReply<_Done> = try await self.withCallID(on: actor.id, target: target) { callID in
12311231
var invocation = InvocationMessage(
12321232
callID: callID,
@@ -1255,8 +1255,10 @@ extension ClusterSystem {
12551255
) async throws -> Reply
12561256
where Reply: AnyRemoteCallReply
12571257
{
1258+
// Make an UUID for the remote call (so we can accept a reply for it)
12581259
let callID = UUID()
12591260

1261+
// Prepare timeout handling
12601262
let timeout = RemoteCall.timeout ?? self.settings.remoteCall.defaultTimeout
12611263
let timeoutTask: Task<Void, Error> = Task.detached {
12621264
try await Task.sleep(nanoseconds: UInt64(timeout.nanoseconds))
@@ -1295,6 +1297,7 @@ extension ClusterSystem {
12951297
timeoutTask.cancel()
12961298
}
12971299

1300+
/// Call the body which should perform the actual call!
12981301
let reply: any AnyRemoteCallReply = try await withCheckedThrowingContinuation { continuation in
12991302
self.inFlightCallLock.withLock {
13001303
self._inFlightCalls[callID] = continuation // this is to be resumed from an incoming reply or timeout
@@ -1445,7 +1448,7 @@ extension ClusterSystem {
14451448
throw DeadLetterError(recipient: recipient)
14461449
}
14471450

1448-
try await InstrumentationSystem.tracer.withSpan("\(target)", baggage: baggage, ofKind: .server) { span in
1451+
try await InstrumentationSystem.tracer.withSpan("\(target)", baggage: baggage, ofKind: .server) { _ in
14491452
try await executeDistributedTarget(
14501453
on: actor,
14511454
target: target,

Sources/DistributedCluster/DeadLetters.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ public final class DeadLetterOffice {
204204
}
205205

206206
// in all other cases, we want to log the dead letter:
207-
self.log.notice(
207+
self.log.debug(
208208
"Dead letter was not delivered \(recipientString)",
209209
metadata: { () -> Logger.Metadata in
210210
// TODO: more metadata (from Envelope) (e.g. sender)

Sources/DistributedCluster/InvocationBehavior.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
import Distributed
16-
import InstrumentationBaggage
1716
import struct Foundation.Data
17+
import InstrumentationBaggage
1818

1919
/// Representation of the distributed invocation in the Behavior APIs.
2020
/// This needs to be removed eventually as we remove behaviors.

0 commit comments

Comments
 (0)