diff --git a/Package.swift b/Package.swift index d97c7f39f..fcd7800c8 100644 --- a/Package.swift +++ b/Package.swift @@ -15,6 +15,7 @@ let targets: [PackageDescription.Target] = [ "SwiftProtobuf", "Logging", "Metrics", + "Backtrace", "DistributedActorsConcurrencyHelpers", "CDistributedActorsMailbox", @@ -152,8 +153,10 @@ let dependencies: [Package.Dependency] = [ .package(url: "https://github.com/apple/swift-log.git", from: "1.0.0"), .package(url: "https://github.com/apple/swift-metrics.git", from: "1.0.0"), + .package(url: "https://github.com/ianpartridge/swift-backtrace.git", .branch("master")), + // ~~~ only for samples ~~~ - .package(url: "https://github.com/MrLotU/SwiftPrometheus", .branch("master")), + .package(url: "https://github.com/MrLotU/SwiftPrometheus", .branch("master")) ] let package = Package( diff --git a/Sources/DistributedActors/ActorSystem.swift b/Sources/DistributedActors/ActorSystem.swift index 7130ae7a3..949327a19 100644 --- a/Sources/DistributedActors/ActorSystem.swift +++ b/Sources/DistributedActors/ActorSystem.swift @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +import Backtrace import CDistributedActorsMailbox import Dispatch import DistributedActorsConcurrencyHelpers @@ -124,6 +125,11 @@ public final class ActorSystem { var settings = settings self.name = settings.cluster.node.systemName + // rely on swift-backtrace for pretty backtraces on crashes + if settings.installSwiftBacktrace { + Backtrace.install() + } + // TODO: we should not rely on NIO for futures let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: settings.threadPoolSize) settings.cluster.eventLoopGroup = eventLoopGroup diff --git a/Sources/DistributedActors/ActorSystemSettings.swift b/Sources/DistributedActors/ActorSystemSettings.swift index 41acd7f8a..e02228e4c 100644 --- a/Sources/DistributedActors/ActorSystemSettings.swift +++ b/Sources/DistributedActors/ActorSystemSettings.swift @@ -43,6 +43,9 @@ public struct ActorSystemSettings { } } + /// Installs a global backtrace (on fault) pretty-print facility upon actor system start. + public var installSwiftBacktrace: Bool = true + // FIXME: should have more proper config section public var threadPoolSize: Int = ProcessInfo.processInfo.activeProcessorCount } diff --git a/Sources/DistributedActors/Cluster/ClusterShellState.swift b/Sources/DistributedActors/Cluster/ClusterShellState.swift index 352566836..59033d5b3 100644 --- a/Sources/DistributedActors/Cluster/ClusterShellState.swift +++ b/Sources/DistributedActors/Cluster/ClusterShellState.swift @@ -178,7 +178,7 @@ extension ClusterShellState { switch state { case .initiated(let initiated): - assert(initiated.channel != nil, "Channel should always be present after the initial initialization.") + assert(initiated.channel != nil, "Channel should always be present after the initial initialization, state was: \(state)") _ = initiated.channel?.close() case .wasOfferedHandshake: fatalError("abortOutgoingHandshake was called in a context where the handshake was not an outgoing one! Was: \(state)")