Skip to content

Commit 39c2f4f

Browse files
glbrnttgjcairo
andauthored
Add Client object (#1729)
Co-authored-by: Gus Cairo <[email protected]>
1 parent 74794ce commit 39c2f4f

25 files changed

+1339
-143
lines changed

Sources/GRPCCore/Call/Client/ClientRPCExecutionConfigurationCollection.swift

Lines changed: 0 additions & 76 deletions
This file was deleted.

Sources/GRPCCore/Call/Client/Internal/ClientRPCExecutor.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ enum ClientRPCExecutor {
3535
static func execute<Input: Sendable, Output: Sendable, Result: Sendable>(
3636
request: ClientRequest.Stream<Input>,
3737
method: MethodDescriptor,
38-
configuration: ClientRPCExecutionConfiguration,
38+
configuration: MethodConfiguration,
3939
serializer: some MessageSerializer<Input>,
4040
deserializer: some MessageDeserializer<Output>,
4141
transport: some ClientTransport,

Sources/GRPCCore/Call/Server/RPCRouter.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
/// given method by calling ``removeHandler(forMethod:)``.
2525
///
2626
/// In most cases you won't need to interact with the router directly. Instead you should register
27-
/// your services with ``Server/Services-swift.struct/register(_:)`` which will in turn register
27+
/// your services with ``GRPCServer/Services-swift.struct/register(_:)`` which will in turn register
2828
/// each method with the router.
2929
///
3030
/// You may wish to not serve all methods from your service in which case you can either:

Sources/GRPCCore/ClientError.swift

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/*
2+
* Copyright 2023, gRPC Authors All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/// A runtime error thrown by the client.
18+
///
19+
/// In contrast to ``RPCError``, the ``ClientError`` represents errors which happen at a scope
20+
/// wider than an individual RPC. For example, attempting to start a client which is already
21+
/// stopped would result in a ``ClientError``.
22+
public struct ClientError: Error, Hashable, @unchecked Sendable {
23+
private var storage: Storage
24+
25+
// Ensures the underlying storage is unique.
26+
private mutating func ensureUniqueStorage() {
27+
if !isKnownUniquelyReferenced(&self.storage) {
28+
self.storage = self.storage.copy()
29+
}
30+
}
31+
32+
/// The code indicating the domain of the error.
33+
public var code: Code {
34+
get { self.storage.code }
35+
set {
36+
self.ensureUniqueStorage()
37+
self.storage.code = newValue
38+
}
39+
}
40+
41+
/// A message providing more details about the error which may include details specific to this
42+
/// instance of the error.
43+
public var message: String {
44+
get { self.storage.message }
45+
set {
46+
self.ensureUniqueStorage()
47+
self.storage.message = newValue
48+
}
49+
}
50+
51+
/// The original error which led to this error being thrown.
52+
public var cause: Error? {
53+
get { self.storage.cause }
54+
set {
55+
self.ensureUniqueStorage()
56+
self.storage.cause = newValue
57+
}
58+
}
59+
60+
/// Creates a new error.
61+
///
62+
/// - Parameters:
63+
/// - code: The error code.
64+
/// - message: A description of the error.
65+
/// - cause: The original error which led to this error being thrown.
66+
public init(code: Code, message: String, cause: Error? = nil) {
67+
self.storage = Storage(code: code, message: message, cause: cause)
68+
}
69+
}
70+
71+
extension ClientError: CustomStringConvertible {
72+
public var description: String {
73+
if let cause = self.cause {
74+
return "\(self.code): \"\(self.message)\" (cause: \"\(cause)\")"
75+
} else {
76+
return "\(self.code): \"\(self.message)\""
77+
}
78+
}
79+
}
80+
81+
extension ClientError {
82+
private final class Storage: Hashable {
83+
var code: Code
84+
var message: String
85+
var cause: Error?
86+
87+
init(code: Code, message: String, cause: Error?) {
88+
self.code = code
89+
self.message = message
90+
self.cause = cause
91+
}
92+
93+
func copy() -> Storage {
94+
return Storage(code: self.code, message: self.message, cause: self.cause)
95+
}
96+
97+
func hash(into hasher: inout Hasher) {
98+
hasher.combine(self.code)
99+
hasher.combine(self.message)
100+
}
101+
102+
static func == (lhs: Storage, rhs: Storage) -> Bool {
103+
return lhs.code == rhs.code && lhs.message == rhs.message
104+
}
105+
}
106+
}
107+
108+
extension ClientError {
109+
public struct Code: Hashable, Sendable {
110+
private enum Value {
111+
case clientIsAlreadyRunning
112+
case clientIsNotRunning
113+
case clientIsStopped
114+
case transportError
115+
}
116+
117+
private var value: Value
118+
private init(_ value: Value) {
119+
self.value = value
120+
}
121+
122+
/// At attempt to start the client was made but it is already running.
123+
public static var clientIsAlreadyRunning: Self {
124+
Self(.clientIsAlreadyRunning)
125+
}
126+
127+
/// An attempt to start an RPC was made but the client is not running.
128+
public static var clientIsNotRunning: Self {
129+
Self(.clientIsNotRunning)
130+
}
131+
132+
/// At attempt to start the client was made but it has already stopped.
133+
public static var clientIsStopped: Self {
134+
Self(.clientIsStopped)
135+
}
136+
137+
/// The transport threw an error whilst connected.
138+
public static var transportError: Self {
139+
Self(.transportError)
140+
}
141+
}
142+
}
143+
144+
extension ClientError.Code: CustomStringConvertible {
145+
public var description: String {
146+
String(describing: self.value)
147+
}
148+
}

0 commit comments

Comments
 (0)