我有一个命令行应用程序,它执行以下操作:
- 下载带有 torrent 链接的 RSS 提要
- 将其存储在 sqlite 数据库中并将它们标记为“添加”或“忽略”
- 连接到传输服务器(在我的本地网络中)
- 从标记为“已添加”的 sqlite 加载项目并添加到传输服务器
以上在调试模式下工作正常。但是,当我为发布构建并尝试直接运行或从 launchd 运行时,它总是超时。最相关的代码在main.swift
下面。
private func getTransmissionClient() -> Transmission? {
let client = Transmission(
baseURL: serverConfig.server,
username: serverConfig.username,
password: serverConfig.password)
var cancellables = Set<AnyCancellable>()
let group = DispatchGroup()
group.enter()
print("[INFO] Connecting to client")
client.request(.rpcVersion)
.sink(
receiveCompletion: { _ in group.leave() },
receiveValue: { rpcVersion in
print("[INFO]: Successfully Connected! RPC Version: \(rpcVersion)")
})
.store(in: &cancellables)
let wallTimeout = DispatchWallTime.now() +
DispatchTimeInterval.seconds(serverConfig.secondsTimeout ?? 15)
let res = group.wait(wallTimeout: wallTimeout)
if res == DispatchTimeoutResult.success {
return client
} else {
return nil
}
}
public func updateTransmission() throws {
print("[INFO] [\(Date())] Starting Transmission Update")
let clientOpt = getTransmissionClient()
guard let client = clientOpt else {
print("[ERROR] Failed to connect to transmission client")
exit(1)
}
var cancellables = Set<AnyCancellable>()
let items = try store.getPendingDownload()
print("[INFO] [\(Date())] Adding \(items.count) new items to transmission")
let group = DispatchGroup()
for item in items {
let linkComponents = "\(item.link)".components(separatedBy: "&")
assert(linkComponents.count > 0, "Link seems wrong")
group.enter()
client.request(.add(url: item.link))
.sink(receiveCompletion: { completion in
if case let .failure(error) = completion {
print("[Failure] \(item.title)")
print("[Failure] Details: \(error)")
}
group.leave()
}, receiveValue: { _ in
print("[Success] \(item.title)")
do {
try self.store.update(item: item, with: .downloaded)
} catch {
print("[Error] Couldn't save new status to DB")
}
})
.store(in: &cancellables)
}
let wallTimeout = DispatchWallTime.now() +
DispatchTimeInterval.seconds(serverConfig.secondsTimeout ?? 15)
let res = group.wait(wallTimeout: wallTimeout)
if res == DispatchTimeoutResult.success {
print("Tasks successfully submitted")
} else {
print("Timed out")
exit(1)
}
}
奇怪的是,在我添加数据库之前,代码似乎运行良好。DispatchGroup 以及 Transmission-Swift 客户端已经存在。我猜我所做的事情是被编译器“优化掉”了?这只是猜测,虽然在 StackOverflow 上看到了其他一些问题,但我仍然不清楚。
我正在使用 macOS 10.15 和 Swift 5.2.2。
github中提供了完整代码(链接到有错误的特定提交)