org.apache.flink.runtime.jobmaster.slotpool.SingleLogicalSlot Maven / Gradle / Ivy
The newest version!
/*
* 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.jobmaster.slotpool;
import org.apache.flink.annotation.VisibleForTesting;
import org.apache.flink.runtime.clusterframework.types.AllocationID;
import org.apache.flink.runtime.jobmanager.scheduler.Locality;
import org.apache.flink.runtime.jobmanager.slots.TaskManagerGateway;
import org.apache.flink.runtime.jobmaster.LogicalSlot;
import org.apache.flink.runtime.jobmaster.SlotContext;
import org.apache.flink.runtime.jobmaster.SlotOwner;
import org.apache.flink.runtime.jobmaster.SlotRequestId;
import org.apache.flink.runtime.taskmanager.TaskManagerLocation;
import org.apache.flink.util.Preconditions;
import org.apache.flink.util.concurrent.FutureUtils;
import javax.annotation.Nullable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
/** Implementation of the {@link LogicalSlot}. */
public class SingleLogicalSlot implements LogicalSlot, PhysicalSlot.Payload {
private static final AtomicReferenceFieldUpdater PAYLOAD_UPDATER =
AtomicReferenceFieldUpdater.newUpdater(
SingleLogicalSlot.class, Payload.class, "payload");
private static final AtomicReferenceFieldUpdater STATE_UPDATER =
AtomicReferenceFieldUpdater.newUpdater(SingleLogicalSlot.class, State.class, "state");
private final SlotRequestId slotRequestId;
private final SlotContext slotContext;
// locality of this slot wrt the requested preferred locations
private final Locality locality;
// owner of this slot to which it is returned upon release
private final SlotOwner slotOwner;
private final CompletableFuture releaseFuture;
private volatile State state;
// LogicalSlot.Payload of this slot
private volatile Payload payload;
/** Whether this logical slot will be occupied indefinitely. */
private boolean willBeOccupiedIndefinitely;
@VisibleForTesting
public SingleLogicalSlot(
SlotRequestId slotRequestId,
SlotContext slotContext,
Locality locality,
SlotOwner slotOwner) {
this(slotRequestId, slotContext, locality, slotOwner, true);
}
public SingleLogicalSlot(
SlotRequestId slotRequestId,
SlotContext slotContext,
Locality locality,
SlotOwner slotOwner,
boolean willBeOccupiedIndefinitely) {
this.slotRequestId = Preconditions.checkNotNull(slotRequestId);
this.slotContext = Preconditions.checkNotNull(slotContext);
this.locality = Preconditions.checkNotNull(locality);
this.slotOwner = Preconditions.checkNotNull(slotOwner);
this.willBeOccupiedIndefinitely = willBeOccupiedIndefinitely;
this.releaseFuture = new CompletableFuture<>();
this.state = State.ALIVE;
this.payload = null;
}
@Override
public TaskManagerLocation getTaskManagerLocation() {
return slotContext.getTaskManagerLocation();
}
@Override
public TaskManagerGateway getTaskManagerGateway() {
return slotContext.getTaskManagerGateway();
}
@Override
public Locality getLocality() {
return locality;
}
@Override
public boolean isAlive() {
return state == State.ALIVE;
}
@Override
public boolean tryAssignPayload(Payload payload) {
return PAYLOAD_UPDATER.compareAndSet(this, null, payload);
}
@Nullable
@Override
public Payload getPayload() {
return payload;
}
@Override
public CompletableFuture> releaseSlot(@Nullable Throwable cause) {
if (STATE_UPDATER.compareAndSet(this, State.ALIVE, State.RELEASING)) {
signalPayloadRelease(cause);
returnSlotToOwner(payload.getTerminalStateFuture());
}
return releaseFuture;
}
@Override
public AllocationID getAllocationId() {
return slotContext.getAllocationId();
}
@Override
public SlotRequestId getSlotRequestId() {
return slotRequestId;
}
public static SingleLogicalSlot allocateFromPhysicalSlot(
final SlotRequestId slotRequestId,
final PhysicalSlot physicalSlot,
final Locality locality,
final SlotOwner slotOwner,
final boolean slotWillBeOccupiedIndefinitely) {
final SingleLogicalSlot singleTaskSlot =
new SingleLogicalSlot(
slotRequestId,
physicalSlot,
locality,
slotOwner,
slotWillBeOccupiedIndefinitely);
if (physicalSlot.tryAssignPayload(singleTaskSlot)) {
return singleTaskSlot;
} else {
throw new IllegalStateException(
"BUG: Unexpected physical slot payload assignment failure!");
}
}
// -------------------------------------------------------------------------
// AllocatedSlot.Payload implementation
// -------------------------------------------------------------------------
/**
* A release of the payload by the {@link AllocatedSlot} triggers a release of the payload of
* the logical slot.
*
* @param cause of the payload release
*/
@Override
public void release(Throwable cause) {
if (STATE_UPDATER.compareAndSet(this, State.ALIVE, State.RELEASING)) {
signalPayloadRelease(cause);
}
markReleased();
releaseFuture.complete(null);
}
@Override
public boolean willOccupySlotIndefinitely() {
return willBeOccupiedIndefinitely;
}
private void signalPayloadRelease(Throwable cause) {
tryAssignPayload(TERMINATED_PAYLOAD);
payload.fail(cause);
}
private void returnSlotToOwner(CompletableFuture> terminalStateFuture) {
FutureUtils.assertNoException(
terminalStateFuture.thenRun(
() -> {
if (state == State.RELEASING) {
slotOwner.returnLogicalSlot(this);
}
markReleased();
releaseFuture.complete(null);
}));
}
private void markReleased() {
state = State.RELEASED;
}
// -------------------------------------------------------------------------
// Internal classes
// -------------------------------------------------------------------------
enum State {
ALIVE,
RELEASING,
RELEASED
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy