Simplify running code
This commit is contained in:
parent
34e0b1ac0a
commit
8ee527ac52
|
@ -16,11 +16,9 @@ import Dispatch
|
|||
|
||||
public class EmbeddedEventLoop : EventLoop {
|
||||
|
||||
let queue = DispatchQueue(label: "embeddedEventLoopQueue", qos: .utility)
|
||||
public var inEventLoop: Bool {
|
||||
return true
|
||||
}
|
||||
var isRunning: Bool = false
|
||||
|
||||
var tasks = CircularBuffer<() -> ()>(initialRingCapacity: 2)
|
||||
|
||||
|
@ -46,25 +44,15 @@ public class EmbeddedEventLoop : EventLoop {
|
|||
|
||||
// We're not really running a loop here. Tasks aren't run until run() is called,
|
||||
// at which point we run everything that's been submitted. Anything newly submitted
|
||||
// either gets on that train if it's still moving or
|
||||
// either gets on that train if it's still moving or waits until the next call to run().
|
||||
public func execute(task: @escaping () -> ()) {
|
||||
queue.sync {
|
||||
if isRunning && tasks.isEmpty {
|
||||
task()
|
||||
} else {
|
||||
tasks.append(task)
|
||||
}
|
||||
}
|
||||
tasks.append(task)
|
||||
}
|
||||
|
||||
func run() throws {
|
||||
queue.sync {
|
||||
isRunning = true
|
||||
|
||||
// Execute all tasks that are currently enqueued.
|
||||
while !tasks.isEmpty {
|
||||
tasks.removeFirst()()
|
||||
}
|
||||
func run() {
|
||||
// Execute all tasks that are currently enqueued.
|
||||
while !tasks.isEmpty {
|
||||
tasks.removeFirst()()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,10 +61,15 @@ public class EmbeddedEventLoop : EventLoop {
|
|||
}
|
||||
|
||||
public func shutdownGracefully(queue: DispatchQueue, _ callback: @escaping (Error?) -> Void) {
|
||||
queue.async {
|
||||
run()
|
||||
queue.sync {
|
||||
callback(nil)
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
precondition(tasks.isEmpty, "Embedded event loop freed with unexecuted tasks!")
|
||||
}
|
||||
}
|
||||
|
||||
class EmbeddedChannelCore : ChannelCore {
|
||||
|
|
|
@ -42,6 +42,7 @@ import XCTest
|
|||
testCase(ClientSNITests.allTests),
|
||||
testCase(EchoServerClientTest.allTests),
|
||||
testCase(EmbeddedChannelTest.allTests),
|
||||
testCase(EmbeddedEventLoopTest.allTests),
|
||||
testCase(EventLoopFutureTest.allTests),
|
||||
testCase(EventLoopTest.allTests),
|
||||
testCase(FileRegionTest.allTests),
|
||||
|
|
|
@ -281,7 +281,7 @@ class SniHandlerTest: XCTestCase {
|
|||
while buffer.readableBytes > 0 {
|
||||
let writeableData = buffer.readSlice(length: 1)!
|
||||
try channel.writeInbound(data: writeableData)
|
||||
try loop.run()
|
||||
loop.run()
|
||||
|
||||
XCTAssertNil(channel.readInbound())
|
||||
try channel.pipeline.assertContains(handler: handler)
|
||||
|
@ -296,7 +296,7 @@ class SniHandlerTest: XCTestCase {
|
|||
// Now we're going to complete the promise and run the loop. This should cause the complete
|
||||
// ClientHello to be sent on, and the SniHandler to be removed from the pipeline.
|
||||
continuePromise.succeed(result: ())
|
||||
try loop.run()
|
||||
loop.run()
|
||||
|
||||
let writtenBuffer: ByteBuffer = channel.readInbound()!
|
||||
let writtenData = writtenBuffer.getData(at: writtenBuffer.readerIndex, length: writtenBuffer.readableBytes)
|
||||
|
@ -325,7 +325,7 @@ class SniHandlerTest: XCTestCase {
|
|||
|
||||
// Ok, let's go.
|
||||
try channel.writeInbound(data: buffer)
|
||||
try loop.run()
|
||||
loop.run()
|
||||
|
||||
// The callback should have fired, but the handler should not have
|
||||
// sent on any data and should still be in the pipeline.
|
||||
|
@ -336,7 +336,7 @@ class SniHandlerTest: XCTestCase {
|
|||
// Now we're going to complete the promise and run the loop. This should cause the complete
|
||||
// ClientHello to be sent on, and the SniHandler to be removed from the pipeline.
|
||||
continuePromise.succeed(result: ())
|
||||
try loop.run()
|
||||
loop.run()
|
||||
|
||||
let writtenBuffer: ByteBuffer? = channel.readInbound()
|
||||
if let writtenBuffer = writtenBuffer {
|
||||
|
|
|
@ -160,12 +160,12 @@ class ChannelPipelineTest: XCTestCase {
|
|||
let channel = EmbeddedChannel()
|
||||
_ = try channel.close().wait()
|
||||
let loop = channel.eventLoop as! EmbeddedEventLoop
|
||||
try loop.run()
|
||||
loop.run()
|
||||
|
||||
XCTAssertTrue(loop.inEventLoop)
|
||||
do {
|
||||
try channel.writeOutbound(data: FileRegion(descriptor: -1, readerIndex: 0, endIndex: 0))
|
||||
try loop.run()
|
||||
loop.run()
|
||||
XCTFail("we ran but an error should have been thrown")
|
||||
} catch let err as ChannelError {
|
||||
XCTAssertEqual(err, .ioOnClosedChannel)
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the SwiftNIO open source project
|
||||
//
|
||||
// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors
|
||||
// Licensed under Apache License v2.0
|
||||
//
|
||||
// See LICENSE.txt for license information
|
||||
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// EmbeddedEventLoopTest+XCTest.swift
|
||||
///
|
||||
import XCTest
|
||||
|
||||
///
|
||||
/// NOTE: This file was generated by generate_linux_tests.rb
|
||||
///
|
||||
/// Do NOT edit this file directly as it will be regenerated automatically when needed.
|
||||
///
|
||||
|
||||
extension EmbeddedEventLoopTest {
|
||||
|
||||
static var allTests : [(String, (EmbeddedEventLoopTest) -> () throws -> Void)] {
|
||||
return [
|
||||
("testExecuteDoesNotImmediatelyRunTasks", testExecuteDoesNotImmediatelyRunTasks),
|
||||
("testExecuteWillRunAllTasks", testExecuteWillRunAllTasks),
|
||||
("testExecuteWillRunTasksAddedRecursively", testExecuteWillRunTasksAddedRecursively),
|
||||
("testTasksSubmittedAfterRunDontRun", testTasksSubmittedAfterRunDontRun),
|
||||
("testShutdownGracefullyRunsTasks", testShutdownGracefullyRunsTasks),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the SwiftNIO open source project
|
||||
//
|
||||
// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors
|
||||
// Licensed under Apache License v2.0
|
||||
//
|
||||
// See LICENSE.txt for license information
|
||||
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@testable import NIO
|
||||
import XCTest
|
||||
|
||||
public class EmbeddedEventLoopTest: XCTestCase {
|
||||
func testExecuteDoesNotImmediatelyRunTasks() throws {
|
||||
var callbackRan = false
|
||||
let loop = EmbeddedEventLoop()
|
||||
loop.execute { callbackRan = true }
|
||||
|
||||
XCTAssertFalse(callbackRan)
|
||||
loop.run()
|
||||
XCTAssertTrue(callbackRan)
|
||||
}
|
||||
|
||||
func testExecuteWillRunAllTasks() throws {
|
||||
var runCount = 0
|
||||
let loop = EmbeddedEventLoop()
|
||||
loop.execute { runCount += 1 }
|
||||
loop.execute { runCount += 1 }
|
||||
loop.execute { runCount += 1 }
|
||||
|
||||
XCTAssertEqual(runCount, 0)
|
||||
loop.run()
|
||||
XCTAssertEqual(runCount, 3)
|
||||
}
|
||||
|
||||
func testExecuteWillRunTasksAddedRecursively() throws {
|
||||
var sentinel = 0
|
||||
let loop = EmbeddedEventLoop()
|
||||
|
||||
loop.execute {
|
||||
// This should execute first.
|
||||
XCTAssertEqual(sentinel, 0)
|
||||
sentinel = 1
|
||||
loop.execute {
|
||||
// This should execute third.
|
||||
XCTAssertEqual(sentinel, 2)
|
||||
sentinel = 3
|
||||
}
|
||||
}
|
||||
loop.execute {
|
||||
// This should execute second.
|
||||
XCTAssertEqual(sentinel, 1)
|
||||
sentinel = 2
|
||||
}
|
||||
|
||||
XCTAssertEqual(sentinel, 0)
|
||||
loop.run()
|
||||
XCTAssertEqual(sentinel, 3)
|
||||
}
|
||||
|
||||
func testTasksSubmittedAfterRunDontRun() throws {
|
||||
var callbackRan = false
|
||||
let loop = EmbeddedEventLoop()
|
||||
loop.execute { callbackRan = true }
|
||||
|
||||
XCTAssertFalse(callbackRan)
|
||||
loop.run()
|
||||
loop.execute { callbackRan = false }
|
||||
XCTAssertTrue(callbackRan)
|
||||
loop.run()
|
||||
XCTAssertFalse(callbackRan)
|
||||
}
|
||||
|
||||
func testShutdownGracefullyRunsTasks() throws {
|
||||
var callbackRan = false
|
||||
let loop = EmbeddedEventLoop()
|
||||
loop.execute { callbackRan = true }
|
||||
|
||||
XCTAssertFalse(callbackRan)
|
||||
XCTAssertNoThrow(try loop.syncShutdownGracefully())
|
||||
XCTAssertTrue(callbackRan)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue