Remote target arguments not deinitialised

Hi
Recently we found the strange behaviour with remote target arguments that are decoded with decodeNextArgument<>()
In a few words the argument is a struct holding some references to the class objects, like below

class ClassValue {
    init() { print("ClassValue.init") }
    deinit() { print("ClassValue.deinit") }
}

struct ArgumentType {
    let classValue: ClassValue
    init(_ classValue: ClassValue) { self.classValue = classValue }
}

the simplified invocation decoder decodeNextArgument<> looks like:

public func decodeNextArgument<Argument>() throws -> Argument {
    let classValue = ClassValue()
    return ArgumentType(classValue)
}

We observe the class value initialiser is called each time we perform a call for distributed actor (we see "ClassValue.init" printed out). We would expect to see "ClassValue.deinit" as well, but actually never see it, what can be treated the argument is not properly deinitialised.

Does anybody know is it expected behaviour or not?
May be we are missing something or doing something wrong.

Thanks in advance!

We implemented a minimised test reproducing an issue: external-reproducers/swift/distributed-system-leak at main · ordo-one/external-reproducers · GitHub
Run 'swift test', will see the ClassValue initialiser is being called twice, but deinitialiser only once.

Thanks a lot for reporting, could you please file an issue with that repro on GitHub - apple/swift: The Swift Programming Language and I'll look to it as soon as I can? It's pretty unexpected if that were to happen but who knows... I'll make sure (and have been adding "make sure we don't leak" tests all over the place recently anyway, so that fits that focus I have now).

1 Like
1 Like

Thank you, I’ll have a look

2 Likes

Closing the loop here as well, we can confirm this was indeed leaking and remained unnoticed since a while. The fix is here: [IRGen] Distributed: Destroy loaded arguments after the call by xedin · Pull Request #65874 · apple/swift · GitHub

2 Likes