Skip to content

Instantly share code, notes, and snippets.

@MrMage
Created February 21, 2018 21:52
Show Gist options
  • Save MrMage/bf10b504ec02c558f0b3a1a01b5d25e9 to your computer and use it in GitHub Desktop.
Save MrMage/bf10b504ec02c558f0b3a1a01b5d25e9 to your computer and use it in GitHub Desktop.
Result of exploratory codegen changes to improve the testability of SwiftGRPC generated code (see https://github.com/grpc/grpc-swift/issues/120).
/*
* DO NOT EDIT.
*
* Generated by the protocol buffer compiler.
* Source: Sync/Proto/echo.proto
*
*/
/*
* Copyright 2018, SwiftGRPC Authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Foundation
import Dispatch
import SwiftGRPC
import SwiftProtobuf
/// Type for errors thrown from generated client code.
public enum Echo_EchoClientError : Error {
case endOfStream
case invalidMessageReceived
case error(c: CallResult)
}
/// Get (Unary)
public protocol Echo_EchoGetCall {
/// Cancel the call.
func cancel()
}
/// Get (Unary)
fileprivate final class Echo_EchoGetCallImpl: Echo_EchoGetCall {
private var call : Call
/// Create a call.
init(_ channel: Channel) {
self.call = channel.makeCall("/echo.Echo/Get")
}
/// Run the call. Blocks until the reply is received.
/// - Throws: `BinaryEncodingError` if encoding fails. `CallError` if fails to call. `Echo_EchoClientError` if receives no response.
func run(request: Echo_EchoRequest,
metadata: Metadata) throws -> Echo_EchoResponse {
let sem = DispatchSemaphore(value: 0)
var returnCallResult : CallResult!
var returnResponse : Echo_EchoResponse?
_ = try start(request:request, metadata:metadata) {response, callResult in
returnResponse = response
returnCallResult = callResult
sem.signal()
}
_ = sem.wait(timeout: DispatchTime.distantFuture)
if let returnResponse = returnResponse {
return returnResponse
} else {
throw Echo_EchoClientError.error(c: returnCallResult)
}
}
/// Start the call. Nonblocking.
/// - Throws: `BinaryEncodingError` if encoding fails. `CallError` if fails to call.
func start(request: Echo_EchoRequest,
metadata: Metadata,
completion: @escaping (Echo_EchoResponse?, CallResult)->())
throws -> Echo_EchoGetCall {
let requestData = try request.serializedData()
try call.start(.unary,
metadata:metadata,
message:requestData)
{(callResult) in
if let responseData = callResult.resultData,
let response = try? Echo_EchoResponse(serializedData:responseData) {
completion(response, callResult)
} else {
completion(nil, callResult)
}
}
return self
}
func cancel() {
call.cancel()
}
}
/// Expand (Server Streaming)
public protocol Echo_EchoExpandCall {
/// Call this to wait for a result. Blocking.
func receive() throws -> Echo_EchoResponse
/// Call this to wait for a result. Nonblocking.
func receive(completion:@escaping (Echo_EchoResponse?, Echo_EchoClientError?)->()) throws
/// Cancel the call.
func cancel()
}
public extension Echo_EchoExpandCall {
func receive() throws -> Echo_EchoResponse {
var returnError : Echo_EchoClientError?
var returnResponse : Echo_EchoResponse!
let sem = DispatchSemaphore(value: 0)
do {
try receive() {response, error in
returnResponse = response
returnError = error
sem.signal()
}
_ = sem.wait(timeout: DispatchTime.distantFuture)
}
if let returnError = returnError {
throw returnError
}
return returnResponse
}
}
fileprivate final class Echo_EchoExpandCallImpl: Echo_EchoExpandCall {
private var call : Call
/// Create a call.
init(_ channel: Channel) {
self.call = channel.makeCall("/echo.Echo/Expand")
}
/// Call this once with the message to send. Nonblocking.
func start(request: Echo_EchoRequest,
metadata: Metadata,
completion: @escaping (CallResult) -> ())
throws -> Echo_EchoExpandCall {
let requestData = try request.serializedData()
try call.start(.serverStreaming,
metadata:metadata,
message:requestData,
completion:completion)
return self
}
func receive(completion:@escaping (Echo_EchoResponse?, Echo_EchoClientError?)->()) throws {
do {
try call.receiveMessage() {(responseData) in
if let responseData = responseData {
if let response = try? Echo_EchoResponse(serializedData:responseData) {
completion(response, nil)
} else {
completion(nil, Echo_EchoClientError.invalidMessageReceived)
}
} else {
completion(nil, Echo_EchoClientError.endOfStream)
}
}
}
}
/// Cancel the call.
func cancel() {
call.cancel()
}
}
/// Simple fake implementation of Echo_EchoExpandCall that returns a previously-defined set of results.
class Echo_EchoExpandCallStub: Echo_EchoExpandCall {
var outputs: [Echo_EchoResponse] = []
func receive(completion:@escaping (Echo_EchoResponse?, Echo_EchoClientError?)->()) throws {
if let output = outputs.first {
outputs.removeFirst()
completion(output, nil)
} else {
completion(nil, Echo_EchoClientError.endOfStream)
}
}
func cancel() { }
}
/// Collect (Client Streaming)
public protocol Echo_EchoCollectCall {
/// Call this to send each message in the request stream. Nonblocking.
func send(_ message:Echo_EchoRequest, errorHandler:@escaping (Error)->()) throws
/// Call this to close the connection and wait for a response. Blocking.
func closeAndReceive() throws -> Echo_EchoResponse
/// Call this to close the connection and wait for a response. Nonblocking.
func closeAndReceive(completion:@escaping (Echo_EchoResponse?, Echo_EchoClientError?)->()) throws
/// Cancel the call.
func cancel()
}
public extension Echo_EchoCollectCall {
func closeAndReceive() throws -> Echo_EchoResponse {
var returnError : Echo_EchoClientError?
var returnResponse : Echo_EchoResponse!
let sem = DispatchSemaphore(value: 0)
do {
try closeAndReceive() {response, error in
returnResponse = response
returnError = error
sem.signal()
}
_ = sem.wait(timeout: DispatchTime.distantFuture)
} catch (let error) {
throw error
}
if let returnError = returnError {
throw returnError
}
return returnResponse
}
}
fileprivate final class Echo_EchoCollectCallImpl: Echo_EchoCollectCall {
private var call : Call
/// Create a call.
init(_ channel: Channel) {
self.call = channel.makeCall("/echo.Echo/Collect")
}
/// Call this to start a call. Nonblocking.
func start(metadata:Metadata, completion:@escaping (CallResult)->())
throws -> Echo_EchoCollectCall {
try self.call.start(.clientStreaming, metadata:metadata, completion:completion)
return self
}
func send(_ message:Echo_EchoRequest, errorHandler:@escaping (Error)->()) throws {
let messageData = try message.serializedData()
try call.sendMessage(data:messageData, errorHandler:errorHandler)
}
func closeAndReceive(completion:@escaping (Echo_EchoResponse?, Echo_EchoClientError?)->()) throws {
do {
try call.receiveMessage() {(responseData) in
if let responseData = responseData,
let response = try? Echo_EchoResponse(serializedData:responseData) {
completion(response, nil)
} else {
completion(nil, Echo_EchoClientError.invalidMessageReceived)
}
}
try call.close(completion:{})
} catch (let error) {
throw error
}
}
func cancel() {
call.cancel()
}
}
/// Simple fake implementation of Echo_EchoCollectCall
/// stores sent values for later verification and finall returns a previously-defined result.
class Echo_EchoCollectCallStub: Echo_EchoCollectCall {
var inputs: [Echo_EchoRequest] = []
var output: Echo_EchoResponse?
func send(_ message:Echo_EchoRequest, errorHandler:@escaping (Error)->()) throws {
inputs.append(message)
}
func closeAndReceive(completion:@escaping (Echo_EchoResponse?, Echo_EchoClientError?)->()) throws {
completion(output!, nil)
}
func cancel() { }
}
/// Update (Bidirectional Streaming)
public protocol Echo_EchoUpdateCall {
/// Call this to wait for a result. Blocking.
func receive() throws -> Echo_EchoResponse
/// Call this to wait for a result. Nonblocking.
func receive(completion:@escaping (Echo_EchoResponse?, Echo_EchoClientError?)->()) throws
/// Call this to send each message in the request stream.
func send(_ message:Echo_EchoRequest, errorHandler:@escaping (Error)->()) throws
/// Call this to close the sending connection. Blocking.
func closeSend() throws
/// Call this to close the sending connection. Nonblocking.
func closeSend(completion:@escaping ()->()) throws
/// Cancel the call.
func cancel()
}
public extension Echo_EchoUpdateCall {
func receive() throws -> Echo_EchoResponse {
var returnError : Echo_EchoClientError?
var returnMessage : Echo_EchoResponse!
let sem = DispatchSemaphore(value: 0)
do {
try receive() {response, error in
returnMessage = response
returnError = error
sem.signal()
}
_ = sem.wait(timeout: DispatchTime.distantFuture)
}
if let returnError = returnError {
throw returnError
}
return returnMessage
}
func closeSend() throws {
let sem = DispatchSemaphore(value: 0)
try closeSend() {
sem.signal()
}
_ = sem.wait(timeout: DispatchTime.distantFuture)
}
}
fileprivate final class Echo_EchoUpdateCallImpl: Echo_EchoUpdateCall {
private var call : Call
/// Create a call.
init(_ channel: Channel) {
self.call = channel.makeCall("/echo.Echo/Update")
}
/// Call this to start a call. Nonblocking.
func start(metadata:Metadata, completion:@escaping (CallResult)->())
throws -> Echo_EchoUpdateCall {
try self.call.start(.bidiStreaming, metadata:metadata, completion:completion)
return self
}
func receive(completion:@escaping (Echo_EchoResponse?, Echo_EchoClientError?)->()) throws {
do {
try call.receiveMessage() {(data) in
if let data = data {
if let returnMessage = try? Echo_EchoResponse(serializedData:data) {
completion(returnMessage, nil)
} else {
completion(nil, Echo_EchoClientError.invalidMessageReceived)
}
} else {
completion(nil, Echo_EchoClientError.endOfStream)
}
}
}
}
func send(_ message:Echo_EchoRequest, errorHandler:@escaping (Error)->()) throws {
let messageData = try message.serializedData()
try call.sendMessage(data:messageData, errorHandler:errorHandler)
}
func closeSend(completion:@escaping ()->()) throws {
try call.close() {
completion()
}
}
func cancel() {
call.cancel()
}
}
/// Simple fake implementation of Echo_EchoUpdateCall that returns a previously-defined set of results
/// and stores sent values for later verification.
class Echo_EchoUpdateCallStub: Echo_EchoUpdateCall {
var inputs: [Echo_EchoRequest] = []
var outputs: [Echo_EchoResponse] = []
func receive(completion:@escaping (Echo_EchoResponse?, Echo_EchoClientError?)->()) throws {
if let output = outputs.first {
outputs.removeFirst()
completion(output, nil)
} else {
completion(nil, Echo_EchoClientError.endOfStream)
}
}
func send(_ message:Echo_EchoRequest, errorHandler:@escaping (Error)->()) throws {
inputs.append(message)
}
func closeSend(completion:@escaping ()->()) throws { completion() }
func cancel() { }
}
/// Instantiate Echo_EchoServiceImpl, then call methods of this protocol to make API calls.
public protocol Echo_EchoService {
var channel: Channel { get }
/// This metadata will be sent with all requests.
var metadata: Metadata { get }
/// This property allows the service host name to be overridden.
/// For example, it can be used to make calls to "localhost:8080"
/// appear to be to "example.com".
var host : String { get }
/// This property allows the service timeout to be overridden.
var timeout : TimeInterval { get }
/// Synchronous. Unary.
func get(_ request: Echo_EchoRequest) throws -> Echo_EchoResponse
/// Asynchronous. Unary.
func get(_ request: Echo_EchoRequest,
completion: @escaping (Echo_EchoResponse?, CallResult)->()) throws -> Echo_EchoGetCall
/// Asynchronous. Server-streaming.
/// Send the initial message.
/// Use methods on the returned object to get streamed responses.
func expand(_ request: Echo_EchoRequest, completion: @escaping (CallResult)->())
throws -> Echo_EchoExpandCall
/// Asynchronous. Client-streaming.
/// Use methods on the returned object to stream messages and
/// to close the connection and wait for a final response.
func collect(completion: @escaping (CallResult)->())
throws -> Echo_EchoCollectCall
/// Asynchronous. Bidirectional-streaming.
/// Use methods on the returned object to stream messages,
/// to wait for replies, and to close the connection.
func update(completion: @escaping (CallResult)->())
throws -> Echo_EchoUpdateCall
}
public final class Echo_EchoServiceImpl: Echo_EchoService {
public private(set) var channel: Channel
public var metadata : Metadata
public var host : String {
get {
return self.channel.host
}
set {
self.channel.host = newValue
}
}
public var timeout : TimeInterval {
get {
return self.channel.timeout
}
set {
self.channel.timeout = newValue
}
}
/// Create a client.
public init(address: String, secure: Bool = true) {
SwiftGRPC.initialize()
channel = Channel(address:address, secure:secure)
metadata = Metadata()
}
/// Create a client that makes secure connections with a custom certificate and (optional) hostname.
public init(address: String, certificates: String, host: String?) {
SwiftGRPC.initialize()
channel = Channel(address:address, certificates:certificates, host:host)
metadata = Metadata()
}
/// Synchronous. Unary.
public func get(_ request: Echo_EchoRequest)
throws
-> Echo_EchoResponse {
return try Echo_EchoGetCallImpl(channel).run(request:request, metadata:metadata)
}
/// Asynchronous. Unary.
public func get(_ request: Echo_EchoRequest,
completion: @escaping (Echo_EchoResponse?, CallResult)->())
throws
-> Echo_EchoGetCall {
return try Echo_EchoGetCallImpl(channel).start(request:request,
metadata:metadata,
completion:completion)
}
/// Asynchronous. Server-streaming.
/// Send the initial message.
/// Use methods on the returned object to get streamed responses.
public func expand(_ request: Echo_EchoRequest, completion: @escaping (CallResult)->())
throws
-> Echo_EchoExpandCall {
return try Echo_EchoExpandCallImpl(channel).start(request:request, metadata:metadata, completion:completion)
}
/// Asynchronous. Client-streaming.
/// Use methods on the returned object to stream messages and
/// to close the connection and wait for a final response.
public func collect(completion: @escaping (CallResult)->())
throws
-> Echo_EchoCollectCall {
return try Echo_EchoCollectCallImpl(channel).start(metadata:metadata, completion:completion)
}
/// Asynchronous. Bidirectional-streaming.
/// Use methods on the returned object to stream messages,
/// to wait for replies, and to close the connection.
public func update(completion: @escaping (CallResult)->())
throws
-> Echo_EchoUpdateCall {
return try Echo_EchoUpdateCallImpl(channel).start(metadata:metadata, completion:completion)
}
}
/// Simple fake implementation of Echo_EchoService that returns a previously-defined set of results
/// and stores request values passed into it for later verification.
/// Note: completion blocks are NOT called with this default implementation, and asynchronous unary calls are NOT implemented!
class Echo_EchoServiceStub: Echo_EchoService {
var channel: Channel { fatalError("not implemented") }
var metadata = Metadata()
var host = ""
var timeout: TimeInterval = 0
var getRequests: [Echo_EchoRequest] = []
var getResponses: [Echo_EchoResponse] = []
func get(_ request: Echo_EchoRequest) throws -> Echo_EchoResponse {
getRequests.append(request)
defer { getResponses.removeFirst() }
return getResponses.first!
}
func get(_ request: Echo_EchoRequest,
completion: @escaping (Echo_EchoResponse?, CallResult)->()) throws -> Echo_EchoGetCall {
fatalError("not implemented")
}
var expandRequests: [Echo_EchoRequest] = []
var expandCalls: [Echo_EchoExpandCall] = []
func expand(_ request: Echo_EchoRequest, completion: @escaping (CallResult)->())
throws -> Echo_EchoExpandCall {
expandRequests.append(request)
defer { expandCalls.removeFirst() }
return expandCalls.first!
}
var collectCalls: [Echo_EchoCollectCall] = []
func collect(completion: @escaping (CallResult)->())
throws -> Echo_EchoCollectCall {
defer { collectCalls.removeFirst() }
return collectCalls.first!
}
var updateCalls: [Echo_EchoUpdateCall] = []
func update(completion: @escaping (CallResult)->())
throws -> Echo_EchoUpdateCall {
defer { updateCalls.removeFirst() }
return updateCalls.first!
}
}
/// Type for errors thrown from generated server code.
public enum Echo_EchoServerError : Error {
case endOfStream
}
/// To build a server, implement a class that conforms to this protocol.
public protocol Echo_EchoProvider {
func get(request : Echo_EchoRequest, session : Echo_EchoGetSession) throws -> Echo_EchoResponse
func expand(request : Echo_EchoRequest, session : Echo_EchoExpandSession) throws
func collect(session : Echo_EchoCollectSession) throws
func update(session : Echo_EchoUpdateSession) throws
}
/// Common properties available in each service session.
public protocol Echo_EchoSession {
var requestMetadata : Metadata { get }
var statusCode : StatusCode { get }
var statusMessage : String { get }
var initialMetadata : Metadata { get }
var trailingMetadata : Metadata { get }
}
fileprivate class Echo_EchoSessionImpl: Echo_EchoSession {
var handler : SwiftGRPC.Handler
var requestMetadata : Metadata { return handler.requestMetadata }
var statusCode : StatusCode = .ok
var statusMessage : String = "OK"
var initialMetadata : Metadata = Metadata()
var trailingMetadata : Metadata = Metadata()
init(handler:SwiftGRPC.Handler) {
self.handler = handler
}
}
class Echo_EchoSessionStub: Echo_EchoSession {
var requestMetadata = Metadata()
var statusCode = StatusCode.ok
var statusMessage = "OK"
var initialMetadata = Metadata()
var trailingMetadata = Metadata()
}
// Get (Unary Streaming)
public protocol Echo_EchoGetSession : Echo_EchoSession { }
fileprivate final class Echo_EchoGetSessionImpl : Echo_EchoSessionImpl, Echo_EchoGetSession {
private var provider : Echo_EchoProvider
/// Create a session.
init(handler:SwiftGRPC.Handler, provider: Echo_EchoProvider) {
self.provider = provider
super.init(handler:handler)
}
/// Run the session. Internal.
func run(queue:DispatchQueue) throws {
try handler.receiveMessage(initialMetadata:initialMetadata) {(requestData) in
if let requestData = requestData {
let requestMessage = try Echo_EchoRequest(serializedData:requestData)
let replyMessage = try self.provider.get(request:requestMessage, session: self)
try self.handler.sendResponse(message:replyMessage.serializedData(),
statusCode:self.statusCode,
statusMessage:self.statusMessage,
trailingMetadata:self.trailingMetadata)
}
}
}
}
/// Trivial fake implementation of Echo_EchoGetSession.
class Echo_EchoGetSessionStub : Echo_EchoSessionStub, Echo_EchoGetSession { }
// Expand (Server Streaming)
public protocol Echo_EchoExpandSession : Echo_EchoSession {
/// Send a message. Nonblocking.
func send(_ response: Echo_EchoResponse, completion: @escaping ()->()) throws
}
fileprivate final class Echo_EchoExpandSessionImpl : Echo_EchoSessionImpl, Echo_EchoExpandSession {
private var provider : Echo_EchoProvider
/// Create a session.
init(handler:SwiftGRPC.Handler, provider: Echo_EchoProvider) {
self.provider = provider
super.init(handler:handler)
}
func send(_ response: Echo_EchoResponse, completion: @escaping ()->()) throws {
try handler.sendResponse(message:response.serializedData()) {completion()}
}
/// Run the session. Internal.
func run(queue:DispatchQueue) throws {
try self.handler.receiveMessage(initialMetadata:initialMetadata) {(requestData) in
if let requestData = requestData {
do {
let requestMessage = try Echo_EchoRequest(serializedData:requestData)
// to keep providers from blocking the server thread,
// we dispatch them to another queue.
queue.async {
do {
try self.provider.expand(request:requestMessage, session: self)
try self.handler.sendStatus(statusCode:self.statusCode,
statusMessage:self.statusMessage,
trailingMetadata:self.trailingMetadata,
completion:{})
} catch (let error) {
print("error: \(error)")
}
}
} catch (let error) {
print("error: \(error)")
}
}
}
}
}
/// Simple fake implementation of Echo_EchoExpandSession that returns a previously-defined set of results
/// and stores sent values for later verification.
class Echo_EchoExpandSessionStub : Echo_EchoSessionStub, Echo_EchoExpandSession {
var outputs: [Echo_EchoResponse] = []
func send(_ response: Echo_EchoResponse, completion: @escaping ()->()) throws {
outputs.append(response)
}
func close() throws { }
}
// Collect (Client Streaming)
public protocol Echo_EchoCollectSession : Echo_EchoSession {
/// Receive a message. Blocks until a message is received or the client closes the connection.
func receive() throws -> Echo_EchoRequest
/// Send a response and close the connection.
func sendAndClose(_ response: Echo_EchoResponse) throws
}
fileprivate final class Echo_EchoCollectSessionImpl : Echo_EchoSessionImpl, Echo_EchoCollectSession {
private var provider : Echo_EchoProvider
/// Create a session.
init(handler:SwiftGRPC.Handler, provider: Echo_EchoProvider) {
self.provider = provider
super.init(handler:handler)
}
func receive() throws -> Echo_EchoRequest {
let sem = DispatchSemaphore(value: 0)
var requestMessage : Echo_EchoRequest?
try self.handler.receiveMessage() {(requestData) in
if let requestData = requestData {
requestMessage = try? Echo_EchoRequest(serializedData:requestData)
}
sem.signal()
}
_ = sem.wait(timeout: DispatchTime.distantFuture)
if requestMessage == nil {
throw Echo_EchoServerError.endOfStream
}
return requestMessage!
}
func sendAndClose(_ response: Echo_EchoResponse) throws {
try self.handler.sendResponse(message:response.serializedData(),
statusCode:self.statusCode,
statusMessage:self.statusMessage,
trailingMetadata:self.trailingMetadata)
}
/// Run the session. Internal.
func run(queue:DispatchQueue) throws {
try self.handler.sendMetadata(initialMetadata:initialMetadata) {
queue.async {
do {
try self.provider.collect(session:self)
} catch (let error) {
print("error \(error)")
}
}
}
}
}
/// Simple fake implementation of Echo_EchoCollectSession that returns a previously-defined set of results
/// and stores sent values for later verification.
class Echo_EchoCollectSessionStub: Echo_EchoSessionStub, Echo_EchoCollectSession {
var inputs: [Echo_EchoRequest] = []
var output: Echo_EchoResponse?
func receive() throws -> Echo_EchoRequest {
if let input = inputs.first {
inputs.removeFirst()
return input
} else {
throw Echo_EchoClientError.endOfStream
}
}
func sendAndClose(_ response: Echo_EchoResponse) throws {
output = response
}
func close() throws { }
}
// Update (Bidirectional Streaming)
public protocol Echo_EchoUpdateSession : Echo_EchoSession {
/// Receive a message. Blocks until a message is received or the client closes the connection.
func receive() throws -> Echo_EchoRequest
/// Send a message. Nonblocking.
func send(_ response: Echo_EchoResponse, completion: @escaping ()->()) throws
/// Close a connection. Blocks until the connection is closed.
func close() throws
}
fileprivate final class Echo_EchoUpdateSessionImpl : Echo_EchoSessionImpl, Echo_EchoUpdateSession {
private var provider : Echo_EchoProvider
/// Create a session.
init(handler:SwiftGRPC.Handler, provider: Echo_EchoProvider) {
self.provider = provider
super.init(handler:handler)
}
func receive() throws -> Echo_EchoRequest {
let sem = DispatchSemaphore(value: 0)
var requestMessage : Echo_EchoRequest?
try self.handler.receiveMessage() {(requestData) in
if let requestData = requestData {
do {
requestMessage = try Echo_EchoRequest(serializedData:requestData)
} catch (let error) {
print("error \(error)")
}
}
sem.signal()
}
_ = sem.wait(timeout: DispatchTime.distantFuture)
if let requestMessage = requestMessage {
return requestMessage
} else {
throw Echo_EchoServerError.endOfStream
}
}
func send(_ response: Echo_EchoResponse, completion: @escaping ()->()) throws {
try handler.sendResponse(message:response.serializedData()) {completion()}
}
func close() throws {
let sem = DispatchSemaphore(value: 0)
try self.handler.sendStatus(statusCode:self.statusCode,
statusMessage:self.statusMessage,
trailingMetadata:self.trailingMetadata) {
sem.signal()
}
_ = sem.wait(timeout: DispatchTime.distantFuture)
}
/// Run the session. Internal.
func run(queue:DispatchQueue) throws {
try self.handler.sendMetadata(initialMetadata:initialMetadata) {
queue.async {
do {
try self.provider.update(session:self)
} catch (let error) {
print("error \(error)")
}
}
}
}
}
/// Simple fake implementation of Echo_EchoUpdateSession that returns a previously-defined set of results
/// and stores sent values for later verification.
class Echo_EchoUpdateSessionStub : Echo_EchoSessionStub, Echo_EchoUpdateSession {
var inputs: [Echo_EchoRequest] = []
var outputs: [Echo_EchoResponse] = []
func receive() throws -> Echo_EchoRequest {
if let input = inputs.first {
inputs.removeFirst()
return input
} else {
throw Echo_EchoClientError.endOfStream
}
}
func send(_ response: Echo_EchoResponse, completion: @escaping ()->()) throws {
outputs.append(response)
}
func close() throws { }
}
/// Main server for generated service
public final class Echo_EchoServer {
private var address: String
private var server: SwiftGRPC.Server
private var provider: Echo_EchoProvider?
/// Create a server that accepts insecure connections.
public init(address:String,
provider:Echo_EchoProvider) {
SwiftGRPC.initialize()
self.address = address
self.provider = provider
self.server = SwiftGRPC.Server(address:address)
}
/// Create a server that accepts secure connections.
public init?(address:String,
certificateURL:URL,
keyURL:URL,
provider:Echo_EchoProvider) {
SwiftGRPC.initialize()
self.address = address
self.provider = provider
guard
let certificate = try? String(contentsOf: certificateURL, encoding: .utf8),
let key = try? String(contentsOf: keyURL, encoding: .utf8)
else {
return nil
}
self.server = SwiftGRPC.Server(address:address, key:key, certs:certificate)
}
/// Start the server.
public func start(queue:DispatchQueue = DispatchQueue.global()) {
guard let provider = self.provider else {
fatalError() // the server requires a provider
}
server.run {(handler) in
print("Server received request to " + handler.host
+ " calling " + handler.method
+ " from " + handler.caller
+ " with " + String(describing:handler.requestMetadata) )
do {
switch handler.method {
case "/echo.Echo/Get":
try Echo_EchoGetSessionImpl(handler:handler, provider:provider).run(queue:queue)
case "/echo.Echo/Expand":
try Echo_EchoExpandSessionImpl(handler:handler, provider:provider).run(queue:queue)
case "/echo.Echo/Collect":
try Echo_EchoCollectSessionImpl(handler:handler, provider:provider).run(queue:queue)
case "/echo.Echo/Update":
try Echo_EchoUpdateSessionImpl(handler:handler, provider:provider).run(queue:queue)
default:
// handle unknown requests
try handler.receiveMessage(initialMetadata:Metadata()) {(requestData) in
try handler.sendResponse(statusCode:.unimplemented,
statusMessage:"unknown method " + handler.method,
trailingMetadata:Metadata())
}
}
} catch (let error) {
print("Server error: \(error)")
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment