org.apache.flink.runtime.io.network.partition.DrainablePipelinedSubpartitionView Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.flink.runtime.io.network.partition;
import org.apache.flink.runtime.io.network.partition.ResultSubpartition.BufferAndBacklog;
import javax.annotation.Nullable;
import java.io.IOException;
import static org.apache.flink.util.Preconditions.checkNotNull;
/**
* View over a drainable pipelined in-memory only subpartition.
*/
class DrainablePipelinedSubpartitionView extends PipelinedSubpartitionView {
/** The subpartition this view belongs to. */
private final PipelinedSubpartition parent;
private volatile boolean isConsumable;
DrainablePipelinedSubpartitionView(PipelinedSubpartition parent, BufferAvailabilityListener listener, boolean isConsumable) {
super(parent, listener);
this.parent = checkNotNull(parent);
this.isConsumable = isConsumable;
}
@Nullable
@Override
public BufferAndBacklog getNextBuffer() throws IOException, InterruptedException {
if (super.isReleased()) {
final Throwable failureCause = super.getFailureCause();
if (failureCause != null) {
if (failureCause instanceof IOException) {
throw (IOException) failureCause;
} else {
throw new IllegalStateException("Try to get buffer from released view " + this, failureCause);
}
} else {
throw new IllegalStateException("Try to get buffer from released view " + this);
}
}
// here we check the released state of parent
// because a view which is not consumable could not reach the parent.pollBuffer()
if (parent.isReleased()) {
if (parent.getFailureCause() != null) {
throw new ProducerFailedException(parent.getFailureCause());
} else {
throw new ProducerFailedException(new IllegalStateException("Try to get buffer from released subpartition " + parent));
}
}
if (!isConsumable) {
return null;
}
return super.getNextBuffer();
}
@Override
public boolean isAvailable() {
// here we need to trigger available when view or parent is released
return super.isAvailable() || isReleased() || parent.isReleased();
}
public void allowConsuming() {
isConsumable = true;
}
public boolean isConsumable() {
return isConsumable;
}
@Override
public String toString() {
return String.format("DrainablePipelinedSubpartitionView(index: %d) of InternalResultPartition %s",
parent.index,
parent.parent.getPartitionId());
}
}