Fix #667 Make no ack an enum case
This commit is contained in:
parent
58f51d07a2
commit
23c76417d2
@ -9,18 +9,43 @@
|
|||||||
import XCTest
|
import XCTest
|
||||||
@testable import SocketIO
|
@testable import SocketIO
|
||||||
|
|
||||||
class SocketAckManagerTest: XCTestCase {
|
class SocketAckManagerTest : XCTestCase {
|
||||||
var ackManager = SocketAckManager()
|
var ackManager = SocketAckManager()
|
||||||
|
|
||||||
func testAddAcks() {
|
func testAddAcks() {
|
||||||
let callbackExpection = self.expectation(description: "callbackExpection")
|
let callbackExpection = expectation(description: "callbackExpection")
|
||||||
let itemsArray = ["Hi", "ho"]
|
let itemsArray = ["Hi", "ho"]
|
||||||
|
|
||||||
func callback(_ items: [Any]) {
|
func callback(_ items: [Any]) {
|
||||||
callbackExpection.fulfill()
|
callbackExpection.fulfill()
|
||||||
}
|
}
|
||||||
|
|
||||||
ackManager.addAck(1, callback: callback)
|
ackManager.addAck(1, callback: callback)
|
||||||
ackManager.executeAck(1, with: itemsArray, onQueue: DispatchQueue.main)
|
ackManager.executeAck(1, with: itemsArray, onQueue: DispatchQueue.main)
|
||||||
|
|
||||||
waitForExpectations(timeout: 3.0, handler: nil)
|
waitForExpectations(timeout: 3.0, handler: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testManagerTimeoutAck() {
|
||||||
|
let callbackExpection = expectation(description: "Manager should timeout ack with noAck status")
|
||||||
|
let itemsArray = ["Hi", "ho"]
|
||||||
|
|
||||||
|
func callback(_ items: [Any]) {
|
||||||
|
XCTAssertEqual(items.count, 1, "Timed out ack should have one value")
|
||||||
|
guard let timeoutReason = items[0] as? String else {
|
||||||
|
XCTFail("Timeout reason should be a string")
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
XCTAssertEqual(timeoutReason, SocketAckStatus.noAck.rawValue)
|
||||||
|
|
||||||
|
callbackExpection.fulfill()
|
||||||
|
}
|
||||||
|
|
||||||
|
ackManager.addAck(1, callback: callback)
|
||||||
|
ackManager.timeoutAck(1, onQueue: DispatchQueue.main)
|
||||||
|
|
||||||
|
waitForExpectations(timeout: 0.2, handler: nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,19 +22,24 @@
|
|||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
import Dispatch
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
public enum SocketAckStatus : String {
|
||||||
|
case noAck = "NO ACK"
|
||||||
|
}
|
||||||
|
|
||||||
private struct SocketAck : Hashable {
|
private struct SocketAck : Hashable {
|
||||||
let ack: Int
|
let ack: Int
|
||||||
var callback: AckCallback!
|
var callback: AckCallback!
|
||||||
var hashValue: Int {
|
var hashValue: Int {
|
||||||
return ack.hashValue
|
return ack.hashValue
|
||||||
}
|
}
|
||||||
|
|
||||||
init(ack: Int) {
|
init(ack: Int) {
|
||||||
self.ack = ack
|
self.ack = ack
|
||||||
}
|
}
|
||||||
|
|
||||||
init(ack: Int, callback: @escaping AckCallback) {
|
init(ack: Int, callback: @escaping AckCallback) {
|
||||||
self.ack = ack
|
self.ack = ack
|
||||||
self.callback = callback
|
self.callback = callback
|
||||||
@ -52,28 +57,28 @@ private func ==(lhs: SocketAck, rhs: SocketAck) -> Bool {
|
|||||||
struct SocketAckManager {
|
struct SocketAckManager {
|
||||||
private var acks = Set<SocketAck>(minimumCapacity: 1)
|
private var acks = Set<SocketAck>(minimumCapacity: 1)
|
||||||
private let ackSemaphore = DispatchSemaphore(value: 1)
|
private let ackSemaphore = DispatchSemaphore(value: 1)
|
||||||
|
|
||||||
mutating func addAck(_ ack: Int, callback: @escaping AckCallback) {
|
mutating func addAck(_ ack: Int, callback: @escaping AckCallback) {
|
||||||
acks.insert(SocketAck(ack: ack, callback: callback))
|
acks.insert(SocketAck(ack: ack, callback: callback))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Should be called on handle queue
|
/// Should be called on handle queue
|
||||||
mutating func executeAck(_ ack: Int, with items: [Any], onQueue: DispatchQueue) {
|
mutating func executeAck(_ ack: Int, with items: [Any], onQueue: DispatchQueue) {
|
||||||
ackSemaphore.wait()
|
ackSemaphore.wait()
|
||||||
defer { ackSemaphore.signal() }
|
defer { ackSemaphore.signal() }
|
||||||
let ack = acks.remove(SocketAck(ack: ack))
|
let ack = acks.remove(SocketAck(ack: ack))
|
||||||
|
|
||||||
onQueue.async() { ack?.callback(items) }
|
onQueue.async() { ack?.callback(items) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Should be called on handle queue
|
/// Should be called on handle queue
|
||||||
mutating func timeoutAck(_ ack: Int, onQueue: DispatchQueue) {
|
mutating func timeoutAck(_ ack: Int, onQueue: DispatchQueue) {
|
||||||
ackSemaphore.wait()
|
ackSemaphore.wait()
|
||||||
defer { ackSemaphore.signal() }
|
defer { ackSemaphore.signal() }
|
||||||
let ack = acks.remove(SocketAck(ack: ack))
|
let ack = acks.remove(SocketAck(ack: ack))
|
||||||
|
|
||||||
onQueue.async() {
|
onQueue.async() {
|
||||||
ack?.callback?(["NO ACK"])
|
ack?.callback?([SocketAckStatus.noAck.rawValue])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user