Created
September 26, 2017 14:24
-
-
Save Bersaelor/393925f7e420cf9696153fcd7c5982f8 to your computer and use it in GitHub Desktop.
Example app Swift4, crashes when run on Linux environment with concurrency > 1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import Dispatch | |
guard CommandLine.arguments.count > 1 else { | |
print("Please add one argument for the number of lanes") | |
exit(0) | |
} | |
var maxConcurrency = Int(CommandLine.arguments[1]) ?? 1 | |
print("Starting to fetch with max \(maxConcurrency) simultaneous fetches") | |
let session = URLSession(configuration: .default) | |
let lanes: [DispatchSemaphore] = (0..<maxConcurrency).map({ _ in DispatchSemaphore(value: 1) }) | |
var laneCtr = 0 | |
func load(url: URL, completion: @escaping (String) -> ()) { | |
let lane = lanes[laneCtr] | |
let currentLaneNr = laneCtr | |
laneCtr = (laneCtr + 1) % maxConcurrency | |
lane.wait() | |
completion("[\(currentLaneNr)]Fetched: Starting to fetch \(url)") | |
let dataTask = session.dataTask(with: url) { (data,response, error) in | |
defer { lane.signal() } | |
if let error = error { | |
completion("[\(currentLaneNr)]Encountered error: \(error.localizedDescription)") | |
} else { | |
completion("[\(currentLaneNr)]Fetched: \(data?.count ?? 0) bytes of data") | |
} | |
} | |
dataTask.resume() | |
} | |
func fetch() { | |
let urlString = "https://github.com/search?q=\(randomInt())" | |
guard let url = URL(string: urlString) else { return } | |
load(url: url) { print($0) } | |
} | |
func randomInt() -> UInt32 { | |
#if os(Linux) | |
return UInt32(random()) | |
#else | |
return arc4random() | |
#endif | |
} | |
func randomTime() -> Double { | |
#if os(Linux) | |
return Double(random()) / Double(Int.max) | |
#else | |
return Double(arc4random()) / Double(UInt32.max) | |
#endif | |
} | |
func delayFetch() { | |
let delay = randomTime() | |
DispatchQueue.main.asyncAfter(deadline: .now() + delay) { | |
//print("delay \(delay)") | |
fetch() | |
delayFetch() | |
} | |
} | |
delayFetch() | |
delayFetch() | |
RunLoop.main.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example illustrating the bug discussed in https://bugs.swift.org/browse/SR-5936?page=com.atlassian.jira.plugin.system.issuetabpanels%3Aall-tabpanel