Compare commits

...
3 Commits
Author SHA1 Message Date
Nikolay Edigaryev eaec015edf Fetcher: re-use URLSession (#976)
Otherwise we start to periodically get RST's from GitHub, possibly
because of too many connection opens, which has an effect of cancelling
previously received bytes.

These RST's can be observed in tcpdump/Wireshark or Console, emitted
from the libusrtcp.dylib library, com.apple.network subsystem, for the
Tart process:

>tcp_input [C59.1.1.1:3] flags=[R] seq=1805021659, ack=0, win=0 state=CLOSED rcv_nxt=1805021659, snd_una=1752355607

You can also observe the "Received Bytes" in "Activity Monitor" for
the Tart process while pulling ghcr.io/cirruslabs/macos-runner:sequoia,
and this value will periodically decrease.
2024-12-17 23:41:24 +04:00
Nikolay Edigaryev e27da23f4c Fetcher: avoid response deadlock (#975) 2024-12-17 01:19:06 +04:00
Nikolay Edigaryev e6a30b07e3 clone: actually reclaim unallocated bytes (#974) 2024-12-17 00:25:07 +04:00
2 changed files with 18 additions and 11 deletions
+1 -1
View File
@@ -77,7 +77,7 @@ struct Clone: AsyncParsableCommand {
// So, once we clone the VM let's try to claim the rest of space for the VM to run without errors.
let unallocatedBytes = try sourceVM.sizeBytes() - sourceVM.allocatedSizeBytes()
if unallocatedBytes > 0 {
try Prune.reclaimIfNeeded(UInt64(), sourceVM)
try Prune.reclaimIfNeeded(UInt64(unallocatedBytes), sourceVM)
}
}, onCancel: {
try? FileManager.default.removeItem(at: tmpVMDir.baseURL)
+17 -10
View File
@@ -1,6 +1,6 @@
import Foundation
fileprivate var urlSessionConfiguration: URLSessionConfiguration {
fileprivate var urlSession: URLSession = {
let config = URLSessionConfiguration.default
// Harbor expects a CSRF token to be present if the HTTP client
@@ -13,14 +13,15 @@ fileprivate var urlSessionConfiguration: URLSessionConfiguration {
// [2]: https://github.com/cirruslabs/tart/issues/295
config.httpShouldSetCookies = false
return config
}
return URLSession(configuration: config)
}()
class Fetcher {
static func fetch(_ request: URLRequest, viaFile: Bool = false, progress: Progress? = nil) async throws -> (AsyncThrowingStream<Data, Error>, HTTPURLResponse) {
let task = urlSession.dataTask(with: request)
let delegate = Delegate()
let session = URLSession(configuration: urlSessionConfiguration, delegate: delegate, delegateQueue: nil)
let task = session.dataTask(with: request)
task.delegate = delegate
let stream = AsyncThrowingStream<Data, Error> { continuation in
delegate.streamContinuation = continuation
@@ -55,6 +56,7 @@ fileprivate class Delegate: NSObject, URLSessionDataDelegate {
buffer = Data(capacity: Int(capacity))
responseContinuation?.resume(returning: response)
responseContinuation = nil
completionHandler(.allow)
}
@@ -76,15 +78,20 @@ fileprivate class Delegate: NSObject, URLSessionDataDelegate {
task: URLSessionTask,
didCompleteWithError error: Error?
) {
if !buffer.isEmpty {
streamContinuation?.yield(buffer)
buffer.removeAll(keepingCapacity: true)
}
if let error = error {
responseContinuation?.resume(throwing: error)
responseContinuation = nil
streamContinuation?.finish(throwing: error)
streamContinuation = nil
} else {
if !buffer.isEmpty {
streamContinuation?.yield(buffer)
buffer.removeAll(keepingCapacity: true)
}
streamContinuation?.finish()
streamContinuation = nil
}
}
}