-
Notifications
You must be signed in to change notification settings - Fork 84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ios: finish bridging between ObjC/Swift #312
Merged
Merged
Changes from 32 commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
441baea
bazel: update to Xcode 10.3
rebello95 c69387a
WIP
rebello95 78cdb91
wip so i can switch branches
rebello95 69bd771
implement EnvoyBuilder
rebello95 423a736
lazily initialize engine
rebello95 11f7d48
tests
rebello95 7f01381
cleanup
rebello95 3b8162c
Merge remote-tracking branch 'origin/envoybuilder' into objc-bridging
rebello95 33b627e
fixup
rebello95 f24c31b
updates
rebello95 fcf1de8
Merge remote-tracking branch 'origin/master' into objc-bridging
rebello95 7dcf9a5
fixup
rebello95 67bce92
build
rebello95 3782a3e
fixup
rebello95 95a32b3
Merge remote-tracking branch 'origin/master' into objc-bridging
rebello95 4192cb2
WIP demo testing E2E
rebello95 abe0e25
call setup
rebello95 fee0aa1
Update ViewController.swift
rebello95 793b81b
more
rebello95 64067c2
tweaks
rebello95 2d0d22c
tests
rebello95 2065e15
send body
rebello95 078b257
remove trailers
rebello95 39ab2c7
fixup
rebello95 df6f6e2
send correct headers
rebello95 43de33e
update for objc
rebello95 af8c50a
add unary
rebello95 d8fbb0f
tests
rebello95 9a494d9
Merge remote-tracking branch 'origin/master' into objc-bridging
rebello95 075659e
cleanup
rebello95 fd9ac92
drop demo changes for this diff
rebello95 7a2013b
cleanup
rebello95 abc7a71
suggestion
rebello95 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 2 additions & 2 deletions
4
library/swift/src/Error.swift → library/swift/src/EnvoyError.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import Foundation | ||
|
||
/// Default implementation of the `StreamEmitter` interface. | ||
@objcMembers | ||
final class EnvoyStreamEmitter { | ||
private let stream: EnvoyHTTPStream | ||
|
||
init(stream: EnvoyHTTPStream) { | ||
self.stream = stream | ||
} | ||
} | ||
|
||
extension EnvoyStreamEmitter: StreamEmitter { | ||
func sendData(_ data: Data) -> StreamEmitter { | ||
self.stream.send(data, close: false) | ||
return self | ||
} | ||
|
||
func sendMetadata(_ metadata: [String: [String]]) -> StreamEmitter { | ||
self.stream.sendMetadata(metadata) | ||
return self | ||
} | ||
|
||
func close(trailers: [String: [String]]) { | ||
self.stream.sendTrailers(trailers) | ||
} | ||
|
||
func cancel() { | ||
_ = self.stream.cancel() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,98 @@ | ||
import Foundation | ||
|
||
/// Callback interface for receiving stream events. | ||
@objc | ||
public protocol ResponseHandler { | ||
/// Dispatch queue upon which callbacks will be called. | ||
var dispatchQueue: DispatchQueue { get } | ||
@objcMembers | ||
public final class ResponseHandler: NSObject { | ||
/// Underlying observer which will be passed to the Envoy Engine. | ||
let underlyingObserver = EnvoyObserver() | ||
|
||
/// Called when response headers are received by the stream. | ||
/// Initialize a new instance of the handler. | ||
/// | ||
/// - parameter headers: The headers of the response. | ||
/// - parameter statusCode: The status code of the response. | ||
func onHeaders(_ headers: [String: [String]], statusCode: Int) | ||
/// - parameter queue: Dispatch queue upon which callbacks will be called. | ||
public init(queue: DispatchQueue = .main) { | ||
self.underlyingObserver.dispatchQueue = queue | ||
} | ||
|
||
/// Called when a data frame is received by the stream. | ||
/// Specify a callback for when response headers are received by the stream. | ||
/// If `endStream` is `true`, the stream is complete. | ||
/// | ||
/// - parameter data: Bytes in the response. | ||
/// - parameter endStream: True if the stream is complete. | ||
func onData(_ data: Data, endStream: Bool) | ||
/// - parameter closure: Closure which will receive the headers, status code, | ||
/// and flag indicating if the stream is headers-only. | ||
@discardableResult | ||
public func onHeaders(_ closure: | ||
@escaping (_ headers: [String: [String]], _ statusCode: Int, _ endStream: Bool) -> Void) | ||
-> ResponseHandler | ||
{ | ||
self.underlyingObserver.onHeaders = { headers, endStream in | ||
closure(headers, ResponseHandler.statusCode(fromHeaders: headers), endStream) | ||
} | ||
|
||
/// Called when response metadata is received by the stream. | ||
return self | ||
rebello95 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
/// Specify a callback for when a data frame is received by the stream. | ||
/// If `endStream` is `true`, the stream is complete. | ||
/// | ||
/// - parameter closure: Closure which will receive the data, | ||
/// and flag indicating if the stream is complete. | ||
@discardableResult | ||
public func onData(_ closure: | ||
@escaping (_ data: Data, _ endStream: Bool) -> Void) | ||
-> ResponseHandler | ||
{ | ||
self.underlyingObserver.onData = closure | ||
return self | ||
} | ||
|
||
/// Specify a callback for when trailers are received by the stream. | ||
/// If the closure is called, the stream is complete. | ||
/// | ||
/// - parameter metadata: The metadata of the response. | ||
/// - parameter endStream: True if the stream is complete. | ||
func onMetadata(_ metadata: [String: [String]], endStream: Bool) | ||
/// - parameter closure: Closure which will receive the trailers. | ||
@discardableResult | ||
public func onTrailers(_ closure: | ||
@escaping (_ trailers: [String: [String]]) -> Void) | ||
-> ResponseHandler | ||
{ | ||
self.underlyingObserver.onTrailers = closure | ||
return self | ||
} | ||
|
||
/// Called when response trailers are received by the stream. | ||
/// Specify a callback for when an internal Envoy exception occurs with the stream. | ||
/// If the closure is called, the stream is complete. | ||
/// | ||
/// - parameter trailers: The trailers of the response. | ||
func onTrailers(_ trailers: [String: [String]]) | ||
/// - parameter closure: Closure which will be called when an error occurs. | ||
@discardableResult | ||
public func onError(_ closure: | ||
@escaping () -> Void) | ||
-> ResponseHandler | ||
{ | ||
self.underlyingObserver.onError = closure | ||
return self | ||
} | ||
|
||
/// Called when an internal Envoy exception occurs with the stream. | ||
/// Specify a callback for when an internal Envoy exception occurs with the stream. | ||
rebello95 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// If the closure is called, the stream is complete. | ||
/// | ||
/// - parameter error: The error that occurred with the stream. | ||
func onError(_ error: Error) | ||
/// - parameter closure: Closure which will be called when the stream is canceled. | ||
@discardableResult | ||
public func onCancel(_ closure: | ||
@escaping () -> Void) | ||
-> ResponseHandler | ||
{ | ||
self.underlyingObserver.onCancel = closure | ||
return self | ||
} | ||
|
||
/// Called when the stream is canceled. | ||
func onCanceled() | ||
// MARK: - Helpers | ||
|
||
/// Called when the stream has been completed. | ||
func onCompletion() | ||
/// Parses out the status code from the provided HTTP headers. | ||
/// | ||
/// - parameter headers: The headers from which to obtain the status. | ||
/// | ||
/// - returns: The HTTP status code from the headers, or 0 if none is set. | ||
static func statusCode(fromHeaders headers: [String: [String]]) -> Int { | ||
return headers[":status"]? | ||
.compactMap(Int.init) | ||
.first ?? 0 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of
startStream
andsendUnary
, I'd suggest:send(request:handler:)
andsend(request:body:handler:)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or
sendRequest(_:handler:)
/sendRequest(_:body:handler:)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather lean towards being clear on the intent (stream/unary) for the end consumer's sake, rather than making them assume based on function parameter signatures
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And of course trailers can be in there too, but since trailers are so rare in normal cases, I'd probably still suggest a signature which excludes or defaults them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand the argument about clarity/specificity, but I doubt most end-users are likely to be thinking in these terms, and I have misgivings because I don't really think this actually is more accurate.
The
startStream
interface is a perfectly appropriate interface for sending a "unary" request, and the current naming sort of makes it sound like you should only use it when you're trying to stream something (a naive user might even think that this is to stream a response, which is completely unrelated).In fact, all HTTP requests are "unary" in the sense that they have a single request and response. I feel like these are semi-GRPC concepts that are leaking in because GRPC layers a stream encoding into a "unary" HTTP request.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess in general, since this is a top level interface, I'm pushing back a little because I feel the naming should be recognizable and understandable to users who don't have a deep familiarity with the underlying concerns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Talked offline - this makes sense. Going to update in a separate PR after merging this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#354