apple / swift-distributed-actors

Peer-to-peer cluster implementation for Swift Distributed Actors
https://apple.github.io/swift-distributed-actors/
Apache License 2.0
604 stars 60 forks source link

SerializationError #1160

Open lyzkov opened 3 months ago

lyzkov commented 3 months ago

I have encountered trouble receiving remote calls after successfully joining from the iOS to the macOS cluster.

13:52:04 error [sact://Boguś@127.0.0.1:7337/system/receptionist][OperationLogDistributedReceptionist.swift:861] Failed to pushOps: DistributedCluster.OpLogDistributedReceptionist.PushOps
// metadata:
// "actor/id": [$wellKnown: receptionist]
// "error": GenericRemoteCallError(message: "Remote call error of [SerializationError] type occurred")
// "receptionist/peer": [$wellKnown: receptionist]

I am running a sample project on the macOS cluster on 192.168.1.8:8228. The same philosopher dining sample was copied to a simple iOS app with little modification:

final class DiningPhilosophers {
    private var forks: [Fork] = []
    private var philosophers: [Philosopher] = []

    func run(for duration: Duration) async throws {
        let system = await ClusterSystem("Boguś") { settings in
            settings.bindPort = 7337
            settings.remoteCall.codableErrorAllowance = .all
        }

        system.cluster.join(host: "192.168.1.8", port: 8228)
        try await self.ensureCluster([system], within: .seconds(10))

        let leftFork = Fork(name: "fork-6", actorSystem: system)
        let rightFork = Fork(name: "fork-7", actorSystem: system)
        let bogus = Philosopher(
            name: "Boguś",
            leftFork: leftFork,
            rightFork: rightFork,
            actorSystem: system
        )

        await system.receptionist.checkIn(bogus, with: .thinkers)

        var thinkers: WeakActorDictionary<Philosopher> = [:]
        for await philosopher in await system.receptionist.listing(of: .thinkers) {
            print("Philosopher # \(philosopher.hashValue) exists!")
            thinkers.insert(philosopher)
        }

        try system.park(atMost: duration)
    }

    private func ensureCluster(_ systems: [ClusterSystem], within: Duration) async throws {
        let nodes = Set(systems.map(\.settings.bindNode))

        try await withThrowingTaskGroup(of: Void.self) { group in
            for system in systems {
                group.addTask {
                    try await system.cluster.waitFor(nodes, .up, within: within)
                }
            }
            // loop explicitly to propagagte any error that might have been thrown
            for try await _ in group {}
        }
    }
}

How can I fix it?

akbashev commented 1 month ago

@lyzkov is this example from repo?

lyzkov commented 1 month ago

It's from my sample from DiningPhilosophers example project. Looks like serializer issue.

Topic off.

Are you developing open source library for peer connectivity in Swift? That sounds very promising for Apple. There are already a couple of 3rd party libraries for that. I'm curious how you would solve and implement Peer Discovery and Message Propagation in Distributed Actors System? I like how you manage objects concurrently. That brings opportunity to distribute computations as well.

Thank you for your support. I'll keep eye on you Q2 next year.

akbashev commented 2 weeks ago

@lyzkov can you check if Fork or Philosopher are non-private? There will be .unableToSummonTypeFromManifest serialization error if they are.

As per library—I'm not an Apple employee, so can't comment here much. 🙂

lyzkov commented 2 weeks ago

@lyzkov can you check if Fork or Philosopher are non-private? There will be .unableToSummonTypeFromManifest serialization error if they are.

There are no such errors. Only those mentioned earlier. However, after a while, I've noticed that the modified sample works. Although I'm not sure about receiving messages from actors checked in, the transfer of data from the remote ghost seems successful. It would be super nice if I could establish a remote call of the actor's method. ^^

As per library—I'm not an Apple employee, so can't comment here much. 🙂

I discovered your project from Apple Developer's official newsletter. I was thinking that Distributed Actors is a project supported internally by Apple... Quite interesting because it's also very well suited to the Swift Evolution with an emphasis on Task Distribution as the natural implication of Task Concurrency.