/*
* Copyright 2016 the original author or authors.
*
* 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.
*/
package org.gradle.process.internal.worker.request;
import org.gradle.internal.UncheckedException;
import org.gradle.internal.dispatch.StreamCompletion;
import org.gradle.internal.remote.internal.hub.StreamFailureHandler;
import org.gradle.process.internal.worker.WorkerProcessException;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class Receiver implements ResponseProtocol, StreamCompletion, StreamFailureHandler {
private static final Object NULL = new Object();
private static final Object END = new Object();
private final BlockingQueue<Object> received = new ArrayBlockingQueue<Object>(10);
private final String baseName;
private Object next;
public Receiver(String baseName) {
this.baseName = baseName;
}
public boolean awaitNextResult() {
try {
if (next == null) {
next = received.take();
}
} catch (InterruptedException e) {
throw UncheckedException.throwAsUncheckedException(e);
}
return next != END;
}
public Object getNextResult() throws Throwable {
awaitNextResult();
Object next = this.next;
if (next == END) {
throw new IllegalStateException("No response received.");
}
this.next = null;
if (next instanceof Failure) {
Failure failure = (Failure) next;
throw failure.failure;
}
return next == NULL ? null : next;
}
@Override
public void handleStreamFailure(Throwable t) {
failed(t);
}
@Override
public void endStream() {
try {
received.put(END);
} catch (InterruptedException e) {
throw UncheckedException.throwAsUncheckedException(e);
}
}
@Override
public void completed(Object result) {
try {
received.put(result == null ? NULL : result);
} catch (InterruptedException e) {
throw UncheckedException.throwAsUncheckedException(e);
}
}
@Override
public void infrastructureFailed(Throwable failure) {
failed(WorkerProcessException.runFailed(baseName, failure));
}
@Override
public void failed(Throwable failure) {
try {
received.put(new Failure(failure));
} catch (InterruptedException e) {
throw UncheckedException.throwAsUncheckedException(e);
}
}
static class Failure {
final Throwable failure;
public Failure(Throwable failure) {
this.failure = failure;
}
}
}