下面列出了io.grpc.Status#getCode ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@VisibleForTesting
public QueueEntry dispatchOperation(MatchListener listener)
throws IOException, InterruptedException {
while (!backplane.isStopped()) {
listener.onWaitStart();
try {
List<Platform.Property> provisions = new ArrayList<>();
QueueEntry queueEntry = backplane.dispatchOperation(provisions);
if (queueEntry != null) {
return queueEntry;
}
} catch (IOException e) {
Status status = Status.fromThrowable(e);
if (status.getCode() != Code.UNAVAILABLE && status.getCode() != Code.DEADLINE_EXCEEDED) {
throw e;
}
}
listener.onWaitEnd();
}
throw new IOException(Status.UNAVAILABLE.withDescription("backplane is stopped").asException());
}
/**
* Extracts the gRPC status from the {@link HttpHeaders}, closing the {@link HttpStreamReader} for a
* successful response, then delivering the status to the {@link TransportStatusListener}.
*/
public static void reportStatus(HttpHeaders headers,
HttpStreamReader reader,
TransportStatusListener transportStatusListener) {
final String grpcStatus = headers.get(GrpcHeaderNames.GRPC_STATUS);
Status status = Status.fromCodeValue(Integer.valueOf(grpcStatus));
if (status.getCode() == Status.OK.getCode()) {
// Successful response, finish delivering messages before returning the status.
reader.closeDeframer();
}
final String grpcMessage = headers.get(GrpcHeaderNames.GRPC_MESSAGE);
if (grpcMessage != null) {
status = status.withDescription(StatusMessageEscaper.unescape(grpcMessage));
}
final String grpcThrowable = headers.get(GrpcHeaderNames.ARMERIA_GRPC_THROWABLEPROTO_BIN);
if (grpcThrowable != null) {
status = addCause(status, grpcThrowable);
}
final Metadata metadata = MetadataUtil.copyFromHeaders(headers);
transportStatusListener.transportReportStatus(status, metadata);
}
protected Action expectAction(Operation operation) throws InterruptedException {
try {
ExecuteOperationMetadata metadata = expectExecuteOperationMetadata(operation);
if (metadata == null) {
return null;
}
ByteString actionBlob = getBlob(metadata.getActionDigest());
if (actionBlob != null) {
return Action.parseFrom(actionBlob);
}
} catch (IOException e) {
Status status = Status.fromThrowable(e);
if (status.getCode() != io.grpc.Status.Code.NOT_FOUND) {
logger.log(Level.SEVERE, "error retrieving action", e);
}
}
return null;
}
private void iterate(boolean isReset) throws IOException {
try {
client.run(jedis -> subscribe(jedis, isReset));
} catch (IOException e) {
Status status = Status.fromThrowable(e);
switch (status.getCode()) {
case DEADLINE_EXCEEDED:
case UNAVAILABLE:
logger.log(Level.WARNING, "failed to subscribe", e);
/* ignore */
break;
default:
throw e;
}
}
}
@Override
public void rstStream(int streamId, ErrorCode errorCode) {
logger.logRstStream(OkHttpFrameLogger.Direction.INBOUND, streamId, errorCode);
Status status = toGrpcStatus(errorCode).augmentDescription("Rst Stream");
boolean stopDelivery =
(status.getCode() == Code.CANCELLED || status.getCode() == Code.DEADLINE_EXCEEDED);
synchronized (lock) {
OkHttpClientStream stream = streams.get(streamId);
if (stream != null) {
PerfMark.event("OkHttpClientTransport$ClientFrameHandler.rstStream",
stream.transportState().tag());
finishStream(
streamId, status,
errorCode == ErrorCode.REFUSED_STREAM ? RpcProgress.REFUSED : RpcProgress.PROCESSED,
stopDelivery, null, null);
}
}
}
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
ServerCall<ReqT, RespT> wrappedCall = new ForwardingServerCall.SimpleForwardingServerCall<ReqT, RespT>(call) {
@Override
public void sendMessage(RespT message) {
super.sendMessage(message);
}
@Override
public void close(Status status, Metadata trailers) {
Throwable exception;
Status newStatus;
if (
status.getCode() == Status.Code.UNKNOWN
&& status.getDescription() == null
&& (exception = status.getCause()) != null
&& (newStatus = statusForException(exception)) != null
) {
status = newStatus
.withCause(exception)
.withDescription(stacktraceToString(exception));
}
super.close(status, trailers);
}
};
return next.startCall(wrappedCall, headers);
}
void finishStream(CronetClientStream stream, Status status) {
synchronized (lock) {
if (streams.remove(stream)) {
boolean isCancelled = (status.getCode() == Code.CANCELLED
|| status.getCode() == Code.DEADLINE_EXCEEDED);
stream.transportState().transportReportStatus(status, isCancelled, new Metadata());
} else {
return;
}
}
stopIfNecessary();
}
@Override
public void rstStream(int streamId, ErrorCode errorCode) {
Status status = toGrpcStatus(errorCode).augmentDescription("Rst Stream");
boolean stopDelivery =
(status.getCode() == Code.CANCELLED || status.getCode() == Code.DEADLINE_EXCEEDED);
finishStream(
streamId, status,
errorCode == ErrorCode.REFUSED_STREAM ? RpcProgress.REFUSED : RpcProgress.PROCESSED,
stopDelivery, null, null);
}
private void assertRstStreamReceived(Status status) {
if (!status.getCode().equals(Status.Code.UNAVAILABLE)) {
throw new AssertionError("Wrong status code. Expected: " + Status.Code.UNAVAILABLE
+ " Received: " + status.getCode());
}
String http2ErrorPrefix = "HTTP/2 error code: NO_ERROR";
if (status.getDescription() == null
|| !status.getDescription().startsWith(http2ErrorPrefix)) {
throw new AssertionError("Wrong HTTP/2 error code. Expected: " + http2ErrorPrefix
+ " Received: " + status.getDescription());
}
}
/**
* Converts the {@link Throwable} to a {@link Status}, taking into account exceptions specific to Armeria as
* well and the protocol package.
*/
public static Status fromThrowable(Throwable t) {
t = unwrap(requireNonNull(t, "t"));
final Status s = Status.fromThrowable(t);
if (s.getCode() != Code.UNKNOWN) {
return s;
}
if (t instanceof ClosedSessionException || t instanceof ClosedChannelException) {
// ClosedChannelException is used any time the Netty channel is closed. Proper error
// processing requires remembering the error that occurred before this one and using it
// instead.
return s;
}
if (t instanceof ClosedStreamException) {
return Status.CANCELLED;
}
if (t instanceof UnprocessedRequestException || t instanceof IOException) {
return Status.UNAVAILABLE.withCause(t);
}
if (t instanceof Http2Exception) {
if (t instanceof Http2Exception.StreamException &&
((Http2Exception.StreamException) t).error() == Http2Error.CANCEL) {
return Status.CANCELLED;
}
return Status.INTERNAL.withCause(t);
}
if (t instanceof TimeoutException) {
return Status.DEADLINE_EXCEEDED.withCause(t);
}
if (t instanceof ContentTooLargeException) {
return Status.RESOURCE_EXHAUSTED.withCause(t);
}
return s;
}
private boolean statusEquals(Status sourceStatus, Status... potentialStatus) {
for (Status status : potentialStatus) {
if (sourceStatus.getCode() == status.getCode()) {
return true;
}
}
return false;
}
public static Status statusFromThrowable(Throwable t) {
Status s = Status.fromThrowable(t);
if (s.getCode() != Status.Code.UNKNOWN) {
return s;
}
if (t instanceof ClosedChannelException) {
// ClosedChannelException is used any time the Netty channel is closed. Proper error
// processing requires remembering the error that occurred before this one and using it
// instead.
//
// Netty uses an exception that has no stack trace, while we would never hope to show this to
// users, if it happens having the extra information may provide a small hint of where to
// look.
ClosedChannelException extraT = new ClosedChannelException();
extraT.initCause(t);
return Status.UNKNOWN.withDescription("channel closed").withCause(extraT);
}
if (t instanceof IOException) {
return Status.UNAVAILABLE.withDescription("io exception").withCause(t);
}
if (t instanceof UnresolvedAddressException) {
return Status.UNAVAILABLE.withDescription("unresolved address").withCause(t);
}
if (t instanceof Http2Exception) {
return Status.INTERNAL.withDescription("http2 exception").withCause(t);
}
return s;
}
/**
* Wraps call to unregisterSshTunnelingKey.
*
* @param requestId the request ID for the request
* @param minaSshdServiceId the minasshd service ID
* @param keyId the key ID
* @return the response
* @throws CcmException if an exception occurs
*/
public UnregisterSshTunnelingKeyResponse unregisterSshTunnelingKey(
String requestId, String minaSshdServiceId, String keyId) throws CcmException {
checkNotNull(requestId);
checkNotNull(minaSshdServiceId);
checkNotNull(keyId);
MinaSshdManagementBlockingStub blockingStub = newStub(requestId);
UnregisterSshTunnelingKeyRequest.Builder requestBuilder = UnregisterSshTunnelingKeyRequest.newBuilder()
.setMinaSshdServiceId(minaSshdServiceId)
.setKeyId(keyId);
try {
LOGGER.debug("Calling unregisterSshTunnelingKey with requestId: {}, minaSshdServiceId: {}, keyId: {}",
requestId, minaSshdServiceId, keyId);
UnregisterSshTunnelingKeyResponse response = blockingStub.unregisterSshTunnelingKey(requestBuilder.build());
if (response == null) {
throw new CcmException("Got null response from MinaSshdManagementService unregisterSshTunnelingKey gRPC call", false);
} else {
return response;
}
} catch (StatusRuntimeException e) {
String message = "MinaSshdManagementService unregisterSshTunnelingKey gRPC call failed: " + e.getMessage();
Status status = e.getStatus();
Status.Code code = status.getCode();
boolean retryable = GrpcUtil.isRetryable(code);
LOGGER.debug("Got status code: {}, retryable: {}", code, retryable);
throw new CcmException(message, e, retryable);
}
}
private void addBlobsLocation(List<Digest> digests, String name) {
while (!backplane.isStopped()) {
try {
backplane.addBlobsLocation(digests, name);
return;
} catch (IOException e) {
Status status = Status.fromThrowable(e);
if (status.getCode() != Code.UNAVAILABLE && status.getCode() != Code.DEADLINE_EXCEEDED) {
throw status.asRuntimeException();
}
}
}
throw Status.UNAVAILABLE.withDescription("backplane was stopped").asRuntimeException();
}
private InputStream fetchBlobFromRemoteWorker(
Digest blobDigest,
Deque<String> workers,
long offset,
long deadlineAfter,
TimeUnit deadlineAfterUnits,
RequestMetadata requestMetadata)
throws IOException, InterruptedException {
String worker = workers.removeFirst();
try {
Instance instance = workerStub(worker);
InputStream input =
instance.newBlobInput(
blobDigest, offset, deadlineAfter, deadlineAfterUnits, requestMetadata);
// ensure that if the blob cannot be fetched, that we throw here
input.available();
if (Thread.interrupted()) {
throw new InterruptedException();
}
return input;
} catch (StatusRuntimeException e) {
Status st = Status.fromThrowable(e);
if (st.getCode() == Code.UNAVAILABLE || st.getCode() == Code.UNIMPLEMENTED) {
// for now, leave this up to schedulers
onUnavailable.accept(worker, e, "getBlob(" + DigestUtil.toString(blobDigest) + ")");
} else if (st.getCode() == Code.NOT_FOUND) {
// ignore this, the worker will update the backplane eventually
} else if (st.getCode() != Code.DEADLINE_EXCEEDED && SHARD_IS_RETRIABLE.test(st)) {
// why not, always
workers.addLast(worker);
} else if (st.getCode() == Code.CANCELLED) {
throw new InterruptedException();
} else {
throw e;
}
}
throw new NoSuchFileException(DigestUtil.toString(blobDigest));
}
private void removeWorker(String name) {
try {
backplane.removeWorker(name, "removing self prior to initialization");
} catch (IOException e) {
Status status = Status.fromThrowable(e);
if (status.getCode() != Code.UNAVAILABLE && status.getCode() != Code.DEADLINE_EXCEEDED) {
throw status.asRuntimeException();
}
logger.log(INFO, "backplane was unavailable or overloaded, deferring removeWorker");
}
}
ServerCallStreamObserver<ReadResponse> onErrorLogReadObserver(
String name, long offset, ServerCallStreamObserver<ReadResponse> delegate) {
return new UniformDelegateServerCallStreamObserver<ReadResponse>(delegate) {
long responseCount = 0;
long responseBytes = 0;
@Override
public void onNext(ReadResponse response) {
delegate.onNext(response);
responseCount++;
responseBytes += response.getData().size();
}
@Override
public void onError(Throwable t) {
Status status = Status.fromThrowable(t);
if (status.getCode() != Code.NOT_FOUND) {
java.util.logging.Level level = Level.SEVERE;
if (responseCount > 0 && status.getCode() == Code.DEADLINE_EXCEEDED
|| status.getCode() == Code.CANCELLED) {
level = Level.WARNING;
}
String message = format("error reading %s at offset %d", name, offset);
if (responseCount > 0) {
message +=
format(" after %d responses and %d bytes of content", responseCount, responseBytes);
}
logger.log(level, message, t);
}
delegate.onError(t);
}
@Override
public void onCompleted() {
delegate.onCompleted();
}
};
}
/**
* Wraps calls to listMinaSshdServices with an account ID.
*
* @param requestId the request ID for the request
* @param accountId the account ID
* @param serviceIds the minasshd services to list. if null or empty then all minasshd services will be listed
* @return the list of minasshd services
*/
public List<MinaSshdService> listMinaSshdServices(String requestId, String accountId, List<String> serviceIds) throws CcmException {
checkNotNull(requestId);
checkNotNull(accountId);
List<MinaSshdService> groups = new ArrayList<>();
MinaSshdManagementBlockingStub minaSshdManagementBlockingStub = newStub(requestId);
ListMinaSshdServicesRequest.Builder requestBuilder = ListMinaSshdServicesRequest.newBuilder()
.setAccountId(accountId)
.setPageSize(minaSshdManagementClientConfig.getListMinaSshdServicesPageSize());
if (serviceIds != null && !serviceIds.isEmpty()) {
requestBuilder.addAllId(serviceIds);
}
ListMinaSshdServicesResponse response;
do {
try {
LOGGER.debug("Calling listMinaSshdServices with requestId: {}, accountId: {}, serviceIds: [{}]",
requestId, accountId, serviceIds);
response = minaSshdManagementBlockingStub.listMinaSshdServices(requestBuilder.build());
if (response == null) {
throw new CcmException("Got null response from MinaSshdManagementService listMinaSshdServices gRPC call", false);
} else {
List<MinaSshdService> minaSshdServices = response.getMinaSshdServiceList();
if (minaSshdServices == null) {
throw new CcmException("Got null minasshd services in MinaSshdManagementService listMinaSshdServices gRPC response", false);
} else {
groups.addAll(minaSshdServices);
}
}
} catch (StatusRuntimeException e) {
String message = "MinaSshdManagementService listMinaSshdServices gRPC call failed: " + e.getMessage();
Status status = e.getStatus();
Status.Code code = status.getCode();
boolean retryable = GrpcUtil.isRetryable(code);
LOGGER.debug("Got status code: {}, retryable: {}", code, retryable);
throw new CcmException(message, e, retryable);
}
requestBuilder.setPageToken(response.getNextPageToken());
} while (response.hasNextPageToken());
return groups;
}
private String formatStatus(Status status) {
return "{code=" + status.getCode()
+ ", description=" + status.getDescription()
+ ", error=" + (status.getCause() == null ? "N/A" : status.getCause().getMessage())
+ '}';
}
private String formatStatus(Status status) {
return "{code=" + status.getCode()
+ ", description=" + status.getDescription()
+ ", error=" + (status.getCause() == null ? "N/A" : status.getCause().getMessage())
+ '}';
}