Skip to content

Commit

Permalink
Turn the RequestIDProvider enum into a struct (#839)
Browse files Browse the repository at this point in the history
Motivation:

Public enums are bad for API evolution. There's no reason the
RequestIDProvider can't be a struct instead.

Modifications:

- Turn RequestIDProvider into a struct

Result:

- Lower risk of API breakage
  • Loading branch information
glbrntt authored Jun 11, 2020
1 parent 399cfe1 commit 31a03ce
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 13 deletions.
41 changes: 28 additions & 13 deletions Sources/GRPC/ClientOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,25 +74,40 @@ public struct CallOptions {
self.cacheable = false
}

/// How Request IDs should be provided.
public enum RequestIDProvider {
/// Generate a new ID automatically.
case autogenerated
public struct RequestIDProvider {
private enum RequestIDSource {
case `static`(String)
case generated(() -> String)
}

private var source: RequestIDSource
private init(_ source: RequestIDSource) {
self.source = source
}

internal func requestID() -> String {
switch self.source {
case .static(let requestID):
return requestID
case .generated(let generator):
return generator()
}
}

/// Generate a new request ID for each RPC.
public static let autogenerated = RequestIDProvider(.generated({ UUID().uuidString }))

/// Specify an ID to be used.
///
/// - Important: this should only be used when `CallOptions` are passed directly to the call.
/// If it is used for the default options on a client then all calls with have the same ID.
case userDefined(String)

func requestID() -> String {
switch self {
case .autogenerated:
return UUID().uuidString
public static func userDefined(_ requestID: String) -> RequestIDProvider {
return RequestIDProvider(.static(requestID))
}

case .userDefined(let id):
return id
}
/// Provide a factory to generate request IDs.
public static func generated(_ requestIDFactory: @escaping () -> String) -> RequestIDProvider {
return RequestIDProvider(.generated(requestIDFactory))
}
}
}
37 changes: 37 additions & 0 deletions Tests/GRPCTests/RequestIDProviderTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2020, gRPC 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.
*/
@testable import GRPC
import XCTest

class RequestIDProviderTests: GRPCTestCase {
func testUserDefined() {
let provider = CallOptions.RequestIDProvider.userDefined("foo")
XCTAssertEqual(provider.requestID(), "foo")
XCTAssertEqual(provider.requestID(), "foo")
}

func testAutogenerated() {
let provider = CallOptions.RequestIDProvider.autogenerated
XCTAssertNotEqual(provider.requestID(), provider.requestID())
}

func testGenerator() {
let provider = CallOptions.RequestIDProvider.generated {
return "foo"
}
XCTAssertEqual(provider.requestID(), "foo")
}
}
12 changes: 12 additions & 0 deletions Tests/GRPCTests/XCTestManifests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,17 @@ extension ReadStateTests {
]
}

extension RequestIDProviderTests {
// DO NOT MODIFY: This is autogenerated, use:
// `swift test --generate-linuxmain`
// to regenerate.
static let __allTests__RequestIDProviderTests = [
("testAutogenerated", testAutogenerated),
("testGenerator", testGenerator),
("testUserDefined", testUserDefined),
]
}

extension ServerDelayedThrowingTests {
// DO NOT MODIFY: This is autogenerated, use:
// `swift test --generate-linuxmain`
Expand Down Expand Up @@ -746,6 +757,7 @@ public func __allTests() -> [XCTestCaseEntry] {
testCase(MessageEncodingHeaderValidatorTests.__allTests__MessageEncodingHeaderValidatorTests),
testCase(PlatformSupportTests.__allTests__PlatformSupportTests),
testCase(ReadStateTests.__allTests__ReadStateTests),
testCase(RequestIDProviderTests.__allTests__RequestIDProviderTests),
testCase(ServerDelayedThrowingTests.__allTests__ServerDelayedThrowingTests),
testCase(ServerErrorTransformingTests.__allTests__ServerErrorTransformingTests),
testCase(ServerTLSErrorTests.__allTests__ServerTLSErrorTests),
Expand Down

0 comments on commit 31a03ce

Please sign in to comment.