Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.build/
.swiftpm/
Package.resolved
.DS_Store
24 changes: 24 additions & 0 deletions nio-visualiser/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.DS_Store

# Xcode
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
*.xcworkspace
!default.xcworkspace
xcuserdata
profile
*.moved-aside
DerivedData
.idea/
*.xcscheme

# CocoaPods
Pods
Podfile.lock
22 changes: 22 additions & 0 deletions nio-visualiser/NIOAutomation/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
</dict>
</plist>
25 changes: 25 additions & 0 deletions nio-visualiser/NIOAutomation/NIOAutomation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2019 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
//
//===----------------------------------------------------------------------===//

#import <Foundation/Foundation.h>

//! Project version number for NIOAutomation.
FOUNDATION_EXPORT double NIOAutomationVersionNumber;

//! Project version string for NIOAutomation.
FOUNDATION_EXPORT const unsigned char NIOAutomationVersionString[];

// In this header, you should import all the public headers of your framework using statements like #import <NIOAutomation/PublicHeader.h>


159 changes: 159 additions & 0 deletions nio-visualiser/NIOAutomation/NIOAutomation.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2019 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
//
//===----------------------------------------------------------------------===//

import NIO

public struct HandlerID: Hashable {
let uuid: String

public init(_ uuid: String) {
self.uuid = uuid
}
}


private struct HandlerIDIterator: IteratorProtocol {

public typealias Element = HandlerID

public mutating func next() -> HandlerID? {
return HandlerID(UUID().uuidString)
}

public init() {}
}

public struct ChannelHandlerInfo: Equatable, Identifiable {

public static func == (lhs: ChannelHandlerInfo, rhs: ChannelHandlerInfo) -> Bool {
lhs.id.uuid == rhs.id.uuid
}

public enum HandlerType: CustomStringConvertible {
public var description: String {
switch self {
case .inbound:
return "Inbound Handler"
case .outbound:
return "Outbound Handler"
case .duplex:
return "Duplex Handler"
case .head:
return "Head Interception Handler"
case .tail:
return "Tail Interception Handler"
case .interceptor:
return "Interception Handler"
}
}

case inbound
case outbound
case duplex
case head
case tail
case interceptor
}

public struct Name: CustomStringConvertible {
public var description: String {
return string
}

public let string: String

public init(_ string: String) {
self.string = string
}
}

public let id: HandlerID
public let name: Name
public let type: HandlerType

public init(id: HandlerID, name: Name, type: HandlerType) {
self.id = id
self.name = name
self.type = type
}
}



public func pipelineAutomation(handlers: [ChannelHandler],
makeInterceptionHandler: (ChannelHandlerInfo) -> ChannelHandler,
completionHandler: ([ChannelHandlerInfo]) -> Void) -> [ChannelHandler] {
// Initialise the HandlerIDIterator used for obtaining handler ids
var idIterator = HandlerIDIterator()

// Use boolean flag to set first handler type as head
var isFirst = true

// Obtain a list of tuples of handlers and their types
var handlersAndInfos = handlers.flatMap { handler -> [(ChannelHandler, ChannelHandlerInfo)] in

// Save value of isFirst and set it to false
let isHead = isFirst
isFirst = false

// Create info for Interception Handler
let handlerInfo = ChannelHandlerInfo(id: isHead ? .init("Head") : idIterator.next()!, name: isHead ? .init("Head") : .init("Interceptor"), type: isHead ? .head : .interceptor)

// Create Interception Handler
let interceptionHandler = makeInterceptionHandler(handlerInfo)

// Obtain ID for real handler
let id = idIterator.next()!

// Obtain name for real handler
var name = "\(type(of: handler))"

if name.contains("<") {
name = name.split(separator: "<", maxSplits: 2, omittingEmptySubsequences: true)[1].dropLast().description
}

// Compute type for real handler
let inbound = handler is _ChannelInboundHandler
let outbound = handler is _ChannelOutboundHandler
let duplex = inbound && outbound

var type: ChannelHandlerInfo.HandlerType

if (duplex) {
type = .duplex
} else if (inbound) {
type = .inbound
} else if (outbound){
type = .outbound
} else {
preconditionFailure("unknown handler type")
}

let info = ChannelHandlerInfo(id: id, name: .init(name), type: type)

return [(interceptionHandler, handlerInfo), (handler, info)]
}

// Create tail handler
let tailInfo = ChannelHandlerInfo(id: .init("Tail"), name: .init("Tail"), type: .tail)
let tailHandler = makeInterceptionHandler(tailInfo)

// Append tail handler to list of handlers
handlersAndInfos.append((tailHandler, tailInfo))

// Send handler infos to collector
completionHandler(handlersAndInfos.map { $0.1 })

return handlersAndInfos.map { $0.0 }
}
22 changes: 22 additions & 0 deletions nio-visualiser/NIOAutomationTests/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
40 changes: 40 additions & 0 deletions nio-visualiser/NIOAutomationTests/NIOAutomationTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2019 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
//
//===----------------------------------------------------------------------===//

import XCTest
@testable import NIOAutomation

class NIOAutomationTests: XCTestCase {

override func setUp() {
// Put setup code here. This method is called before the invocation of each test method in the class.
}

override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}

func testExample() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}

func testPerformanceExample() {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
}
}

}
Binary file added nio-visualiser/NIOVisualiser.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading