|
|
@@ -0,0 +1,136 @@
|
|
|
+# FAQs
|
|
|
+
|
|
|
+## Logging / Tracing
|
|
|
+
|
|
|
+### Is Logging supported?
|
|
|
+
|
|
|
+Logging is supported by providing a `Logger` from [SwiftLog][swift-log] to the
|
|
|
+relevant configuration object.
|
|
|
+
|
|
|
+For the client:
|
|
|
+
|
|
|
+- `ClientConnection.Builder.withBackgroundActivityLogger` allows a logger to be
|
|
|
+ supplied which logs information at the connection level, relating to things
|
|
|
+ such as connectivity state changes, or connection errors.
|
|
|
+- `CallOptions` allows `logger` to be specified. It is used to log information
|
|
|
+ at the RPC level, such as changes to the state of the RPC. Any connection
|
|
|
+ level metadata will be attached to the logger so that RPC logs may be
|
|
|
+ correlated with connection level changes.
|
|
|
+
|
|
|
+For the server:
|
|
|
+
|
|
|
+- `Server.Builder.withLogger` allows a `logger` to be specified. It is used as a
|
|
|
+ root logger and is passed down to each accepted connection and in turn each
|
|
|
+ RPC on a connection. The logger is made available in the `context` of each
|
|
|
+ RPC handler.
|
|
|
+
|
|
|
+Note that gRPC will not emit logs unless a logger is explicitly provided.
|
|
|
+
|
|
|
+### How can RPCs be traced?
|
|
|
+
|
|
|
+For the client:
|
|
|
+
|
|
|
+If `logger` is set in the `CallOptions` for an RPC then gRPC may attach a
|
|
|
+request ID to the metadata of that logger. This is determined by the value of
|
|
|
+`requestIDProvider` in `CallOptions`. The options for `requestIDProvider`
|
|
|
+include:
|
|
|
+
|
|
|
+- `autogenerated`: a new UUID will be generated (default).
|
|
|
+- `generated(_:)`: the provided callback will be called to generate a new ID.
|
|
|
+- `userDefined(_:)`: the provided value will be used. Note: this option should
|
|
|
+ not be set as a default option on a client as all RPCs would used the same ID.
|
|
|
+- `none`: no request ID will be attached to the logger, this can be useful if a
|
|
|
+ logger already has a request ID associated with it.
|
|
|
+
|
|
|
+If a request ID is attached to the logger's metadata it will use the key
|
|
|
+`grpc_request_id`.
|
|
|
+
|
|
|
+If a request ID is provided and the `requestIDHeader` option is set then gRPC
|
|
|
+will add the ID to the request headers. By default `requestIDHeader` is not set.
|
|
|
+
|
|
|
+## Client Connection Lifecycle
|
|
|
+
|
|
|
+### Is the client's connection long-lived?
|
|
|
+
|
|
|
+The `ClientConnection` is intended to be used as a long-living connection to a
|
|
|
+remote peer. It will manage the underlying network resources automatically,
|
|
|
+creating a connection when necessary and dropping it when it is no longer
|
|
|
+required. However, the user must `close()` the connection when finished with it.
|
|
|
+
|
|
|
+The underlying connection may be in any of the following states:
|
|
|
+
|
|
|
+- Idle: there is no underlying connection.
|
|
|
+- Connecting: an attempt to establish a connection is being made.
|
|
|
+- Ready: the connection has been established, a TLS handshake has completed
|
|
|
+ (if applicable) and the first HTTP/2 settings frame has been received.
|
|
|
+- Transient failure: A transient error occurred either from a ready connection
|
|
|
+ or from a connection attempt. An new connection will be established after some
|
|
|
+ time. (See later sections on connection backoff for more details.)
|
|
|
+- Shutdown: The application requested that the connection be closed, or a
|
|
|
+ connection error occurred and connection re-establishment was disabled. This
|
|
|
+ state is terminal.
|
|
|
+
|
|
|
+The gRPC library [documents][grpc-conn-states] these states in more details.
|
|
|
+Note that not all information linked is applicable to gRPC Swift.
|
|
|
+
|
|
|
+### How can connection states be observed?
|
|
|
+
|
|
|
+A connectivity state delegate may be set using
|
|
|
+`withConnectivityStateDelegate(_:executingOn:)` on the
|
|
|
+`ClientConnection.Builder`.
|
|
|
+
|
|
|
+The delegate is called on the `DispatchQueue` specified by the `executingOn`
|
|
|
+parameter. gRPC will create a `DispatchQueue` if one isn't otherwise specified.
|
|
|
+
|
|
|
+These state changes will also be logged by the `backgroundActivityLogger` (see
|
|
|
+above).
|
|
|
+
|
|
|
+### When will the connection idle?
|
|
|
+
|
|
|
+The connection will be idled (i.e. the underlying connection closed and moved to
|
|
|
+the 'idle' state) if there are no outstanding RPCs for 5 minutes (by default).
|
|
|
+The connection will _not_ be idled if there outstanding RPCs which are not
|
|
|
+sending or receiving messages. This option may be configured using
|
|
|
+`withConnectionIdleTimeout` on the `ClientConnection.Builder`.
|
|
|
+
|
|
|
+Any RPC called after the connection has idled will trigger a connection
|
|
|
+attempt.
|
|
|
+
|
|
|
+### How can I keep a connection alive?
|
|
|
+
|
|
|
+For long-lived, low-activity RPCs it may be beneficial to configure keepalive.
|
|
|
+Doing so will periodically send pings to the remote peer. It may also be used to
|
|
|
+detect unresponsive peers.
|
|
|
+
|
|
|
+See the [gRPC Keepalive][grpc-keepalive] documentation for details.
|
|
|
+
|
|
|
+## RPC Lifecycle
|
|
|
+
|
|
|
+### How do I start an RPC?
|
|
|
+
|
|
|
+RPCs are usually started by invoking a method on a generated client. Each
|
|
|
+generated client relies on an underlying `GRPCChannel` to provide transport.
|
|
|
+
|
|
|
+RPCs can also be made without a generated client by using `AnyServiceClient`.
|
|
|
+This requires the user know the path (i.e. '/echo/Get') and request and response
|
|
|
+types for the RPC.
|
|
|
+
|
|
|
+### Are failing RPCs retried automatically?
|
|
|
+
|
|
|
+RPCs are never automatically retried by gRPC Swift.
|
|
|
+
|
|
|
+The framework cannot determine whether your RPC is idempotent, it is therefore
|
|
|
+not safe for gRPC Swift to automatically retry RPCs for you.
|
|
|
+
|
|
|
+### Deadlines and Timeouts
|
|
|
+
|
|
|
+It's recommended that deadlines are used to enforce a limit on the duration of
|
|
|
+an RPC. Users may set a time limit (either a deadline or a timeout) on the
|
|
|
+`CallOptions` for each call, or as a default on a client. RPCs which have not
|
|
|
+completed before the time limit will be failed with status code 4
|
|
|
+('deadline exceeded').
|
|
|
+
|
|
|
+
|
|
|
+[grpc-conn-states]: connectivity-semantics-and-api.md
|
|
|
+[grpc-keepalive]: keepalive.md
|
|
|
+[swift-log]: https://github.com/apple/swift-log
|