Skip to content

Commit

Permalink
gzip deflate is not needed and add timeout logic
Browse files Browse the repository at this point in the history
sometimes the sofa feed hangs. It could be my device, but this will ensure after 10 seconds, we retry.
  • Loading branch information
erikng committed Jul 16, 2024
1 parent a6f0177 commit 325e9f7
Showing 1 changed file with 16 additions and 53 deletions.
69 changes: 16 additions & 53 deletions Nudge/3rd Party Assets/sofa.swift
Original file line number Diff line number Diff line change
Expand Up @@ -222,52 +222,20 @@ extension MacOSDataFeed {
}

class SOFA: NSObject, URLSessionDelegate {
func decompressGzip(data: Data) -> Data? {
let tempDir = FileManager.default.temporaryDirectory
let compressedFileURL = tempDir.appendingPathComponent(UUID().uuidString)
let decompressedFileURL = tempDir.appendingPathComponent(UUID().uuidString)

do {
// Write compressed data to a temporary file
try data.write(to: compressedFileURL)

// Use gzip to decompress the file
let result = SubProcessUtilities().runProcess(launchPath: "/usr/bin/gzip", arguments: ["--decompress", "--to-stdout", compressedFileURL.path])

// Clean up temporary files
try FileManager.default.removeItem(at: compressedFileURL)

if result.exitCode != 0 {
LogManager.error("gzip failed with status \(result.exitCode): \(result.error)", logger: utilsLog)
return nil
}

// Convert the output string back to Data
guard let decompressedData = result.output.data(using: .utf8) else {
LogManager.error("Failed to convert decompressed output to Data", logger: utilsLog)
return nil
}

return decompressedData
} catch {
LogManager.error("Failed to decompress gzip data using command: \(error.localizedDescription)", logger: utilsLog)
return nil
}
}

func URLSync(url: URL, maxRetries: Int = 3) -> (data: Data?, response: URLResponse?, error: Error?, responseCode: Int?, eTag: String?) {
let semaphore = DispatchSemaphore(value: 0)
let lastEtag = Globals.nudgeDefaults.string(forKey: "LastEtag") ?? ""
var request = URLRequest(url: url)
let config = URLSessionConfiguration.default
config.requestCachePolicy = .useProtocolCachePolicy
let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)

request.addValue("\(Globals.bundleID)/\(VersionManager.getNudgeVersion())", forHTTPHeaderField: "User-Agent")
request.setValue(lastEtag, forHTTPHeaderField: "If-None-Match")
// TODO: I'm saving the Etag and sending it, but due to forcing this into a syncronous call, it is always returning a 200 code. When using this in an asycronous method, it eventually returns the 304 response. I'm not sure how to fix this bug.
request.addValue("gzip, deflate, br", forHTTPHeaderField: "Accept-Encoding") // Force compression for JSON
var attempts = 0

var attempts = 0
var responseData: Data?
var response: URLResponse?
var responseError: Error?
Expand All @@ -278,15 +246,17 @@ class SOFA: NSObject, URLSessionDelegate {
// Retry loop
while attempts < maxRetries {
attempts += 1
let task = session.dataTask(with: request) { [weak self] data, resp, error in
guard let self = self else { return } // To handle self being nil
let task = session.dataTask(with: request) { data, resp, error in
guard let httpResponse = resp as? HTTPURLResponse else {
LogManager.error("Error receiving response: \(error?.localizedDescription ?? "No error information")", logger: utilsLog)
semaphore.signal()
return
}

responseCode = httpResponse.statusCode
response = resp
responseError = error

if responseCode == 200 {
if let etag = httpResponse.allHeaderFields["Etag"] as? String {
eTag = etag
Expand All @@ -295,33 +265,26 @@ class SOFA: NSObject, URLSessionDelegate {

if let encoding = httpResponse.allHeaderFields["Content-Encoding"] as? String {
LogManager.debug("Content-Encoding: \(encoding)", logger: utilsLog)

if encoding == "gzip", let compressedData = data {
responseData = self.decompressGzip(data: compressedData)

if responseData == nil {
LogManager.error("Failed to decompress gzip data", logger: utilsLog)
responseData = data // Fall back to using the original data
} else {
LogManager.debug("Successfully decompressed gzip data", logger: utilsLog)
}
} else {
responseData = data
}
} else {
responseData = data
}

responseData = data

} else if responseCode == 304 {
successfulQuery = true
}

response = resp
responseError = error
semaphore.signal()
}

let timeout = DispatchWorkItem {
task.cancel()
semaphore.signal()
}

DispatchQueue.global().asyncAfter(deadline: .now() + 10, execute: timeout)
task.resume()
semaphore.wait()
timeout.cancel()

if successfulQuery {
break
Expand Down

0 comments on commit 325e9f7

Please sign in to comment.