swim.runtime.AbstractTierBinding Maven / Gradle / Ivy
// Copyright 2015-2019 SWIM.AI inc.
//
// 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 swim.runtime;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
public abstract class AbstractTierBinding extends AbstractSwimRef implements TierBinding {
protected volatile int status;
@Override
public abstract TierContext tierContext();
@Override
public boolean isClosed() {
final int phase = (this.status & PHASE_MASK) >>> PHASE_SHIFT;
return phase == CLOSED_PHASE;
}
@Override
public boolean isOpened() {
final int phase = (this.status & PHASE_MASK) >>> PHASE_SHIFT;
return phase >= OPENED_PHASE;
}
@Override
public boolean isLoaded() {
final int phase = (this.status & PHASE_MASK) >>> PHASE_SHIFT;
return phase >= LOADED_PHASE;
}
@Override
public boolean isStarted() {
final int phase = (this.status & PHASE_MASK) >>> PHASE_SHIFT;
return phase == STARTED_PHASE;
}
protected void activate(TierBinding childTier) {
final int state = this.status & STATE_MASK;
if (state >= STARTING_STATE) {
childTier.start();
} else if (state >= LOADING_STATE) {
childTier.load();
} else if (state >= OPENING_STATE) {
childTier.open();
}
}
@Override
public void open() {
int oldStatus;
int newStatus;
int oldState;
int newState;
int oldPhase;
final int newPhase = OPENED_PHASE;
do {
oldStatus = this.status;
oldState = oldStatus & STATE_MASK;
oldPhase = (oldStatus & PHASE_MASK) >>> PHASE_SHIFT;
if (newPhase > oldPhase) {
if (oldState == CLOSED_STATE) {
newState = OPENING_STATE;
} else {
newState = oldState;
}
newStatus = newState & STATE_MASK | (newPhase << PHASE_SHIFT) & PHASE_MASK;
} else {
newState = oldState;
newStatus = oldStatus;
break;
}
} while (oldStatus != newStatus && !STATUS.compareAndSet(this, oldStatus, newStatus));
if (oldState != newState) {
if (newState == OPENING_STATE) {
willOpen();
convergeState();
}
}
}
@Override
public void load() {
int oldStatus;
int newStatus;
int oldState;
int newState;
int oldPhase;
final int newPhase = LOADED_PHASE;
do {
oldStatus = this.status;
oldState = oldStatus & STATE_MASK;
oldPhase = (oldStatus & PHASE_MASK) >>> PHASE_SHIFT;
if (newPhase > oldPhase) {
if (oldState == OPENED_STATE) {
newState = LOADING_STATE;
} else if (oldState == CLOSED_STATE) {
newState = OPENING_STATE;
} else {
newState = oldState;
}
newStatus = newState & STATE_MASK | (newPhase << PHASE_SHIFT) & PHASE_MASK;
} else {
newState = oldState;
newStatus = oldStatus;
break;
}
} while (oldStatus != newStatus && !STATUS.compareAndSet(this, oldStatus, newStatus));
if (oldState != newState) {
if (newState == LOADING_STATE) {
willLoad();
convergeState();
} else if (newState == OPENING_STATE) {
willOpen();
convergeState();
}
}
}
@Override
public void start() {
int oldStatus;
int newStatus;
int oldState;
int newState;
int oldPhase;
final int newPhase = STARTED_PHASE;
do {
oldStatus = this.status;
oldState = oldStatus & STATE_MASK;
oldPhase = (oldStatus & PHASE_MASK) >>> PHASE_SHIFT;
if (newPhase > oldPhase) {
if (oldState == LOADED_STATE) {
newState = STARTING_STATE;
} else if (oldState == OPENED_STATE) {
newState = LOADING_STATE;
} else if (oldState == CLOSED_STATE) {
newState = OPENING_STATE;
} else {
newState = oldState;
}
newStatus = newState & STATE_MASK | (newPhase << PHASE_SHIFT) & PHASE_MASK;
} else {
newState = oldState;
newStatus = oldStatus;
break;
}
} while (oldStatus != newStatus && !STATUS.compareAndSet(this, oldStatus, newStatus));
if (oldState != newState) {
if (newState == STARTING_STATE) {
willStart();
convergeState();
} else if (newState == LOADING_STATE) {
willLoad();
convergeState();
} else if (newState == OPENING_STATE) {
willOpen();
convergeState();
}
}
}
@Override
public void stop() {
int oldStatus;
int newStatus;
int oldState;
int newState;
int oldPhase;
final int newPhase = LOADED_PHASE;
do {
oldStatus = this.status;
oldState = oldStatus & STATE_MASK;
oldPhase = (oldStatus & PHASE_MASK) >>> PHASE_SHIFT;
if (newPhase < oldPhase) {
if (oldState == STARTED_STATE) {
newState = STOPPING_STATE;
} else {
newState = oldState;
}
newStatus = newState & STATE_MASK | (newPhase << PHASE_SHIFT) & PHASE_MASK;
} else {
newState = oldState;
newStatus = oldStatus;
break;
}
} while (oldStatus != newStatus && !STATUS.compareAndSet(this, oldStatus, newStatus));
if (oldState != newState) {
if (newState == STOPPING_STATE) {
willStop();
convergeState();
}
}
}
@Override
public void unload() {
int oldStatus;
int newStatus;
int oldState;
int newState;
int oldPhase;
final int newPhase = OPENED_PHASE;
do {
oldStatus = this.status;
oldState = oldStatus & STATE_MASK;
oldPhase = (oldStatus & PHASE_MASK) >>> PHASE_SHIFT;
if (newPhase < oldPhase) {
if (oldState == LOADED_STATE) {
newState = UNLOADING_STATE;
} else if (oldState == STARTED_STATE) {
newState = STOPPING_STATE;
} else {
newState = oldState;
}
newStatus = newState & STATE_MASK | (newPhase << PHASE_SHIFT) & PHASE_MASK;
} else {
newState = oldState;
newStatus = oldStatus;
break;
}
} while (oldStatus != newStatus && !STATUS.compareAndSet(this, oldStatus, newStatus));
if (oldState != newState) {
if (newState == UNLOADING_STATE) {
willUnload();
convergeState();
} else if (newState == STOPPING_STATE) {
willStop();
convergeState();
}
}
}
@Override
public void close() {
int oldStatus;
int newStatus;
int oldState;
int newState;
int oldPhase;
final int newPhase = CLOSED_PHASE;
do {
oldStatus = this.status;
oldState = oldStatus & STATE_MASK;
oldPhase = (oldStatus & PHASE_MASK) >>> PHASE_SHIFT;
if (newPhase < oldPhase) {
if (oldState == OPENED_STATE) {
newState = CLOSING_STATE;
} else if (oldState == LOADED_STATE) {
newState = UNLOADING_STATE;
} else if (oldState == STARTED_STATE) {
newState = STOPPING_STATE;
} else {
newState = oldState;
}
newStatus = newState & STATE_MASK | (newPhase << PHASE_SHIFT) & PHASE_MASK;
} else {
newState = oldState;
newStatus = oldStatus;
break;
}
} while (oldStatus != newStatus && !STATUS.compareAndSet(this, oldStatus, newStatus));
if (oldState != newState) {
if (newState == CLOSING_STATE) {
willClose();
convergeState();
} else if (newState == UNLOADING_STATE) {
willUnload();
convergeState();
} else if (newState == STOPPING_STATE) {
willStop();
convergeState();
}
}
}
void convergeState() {
call: do {
int oldStatus;
int newStatus;
int oldState;
int newState;
loop:
do {
oldStatus = this.status;
oldState = oldStatus & STATE_MASK;
final int phase = (oldStatus & PHASE_MASK) >>> PHASE_SHIFT;
switch (oldState) {
case OPENING_STATE:
newState = phase > OPENED_PHASE ? LOADING_STATE : phase < OPENED_PHASE ? CLOSING_STATE : OPENED_STATE;
break;
case LOADING_STATE:
newState = phase > LOADED_PHASE ? STARTING_STATE : phase < LOADED_PHASE ? UNLOADING_STATE : LOADED_STATE;
break;
case STARTING_STATE:
newState = phase < STARTED_PHASE ? STOPPING_STATE : STARTED_STATE;
break;
case STOPPING_STATE:
newState = phase < LOADED_PHASE ? UNLOADING_STATE : phase > LOADED_PHASE ? STARTING_STATE : LOADED_STATE;
break;
case UNLOADING_STATE:
newState = phase < OPENED_PHASE ? CLOSING_STATE : phase > OPENED_PHASE ? LOADING_STATE : OPENED_STATE;
break;
case CLOSING_STATE:
newState = phase > CLOSED_PHASE ? OPENING_STATE : CLOSED_STATE;
break;
default:
newState = oldState;
newStatus = oldStatus;
break loop;
}
newStatus = oldStatus & ~STATE_MASK | newState & STATE_MASK;
} while (oldStatus != newStatus && !STATUS.compareAndSet(this, oldStatus, newStatus));
if (oldState != newState) {
switch (oldState) {
case OPENING_STATE:
didOpen();
break;
case LOADING_STATE:
didLoad();
break;
case STARTING_STATE:
didStart();
break;
case STOPPING_STATE:
didStop();
break;
case UNLOADING_STATE:
didUnload();
break;
case CLOSING_STATE:
final TierContext tierContext = tierContext();
if (tierContext != null) {
tierContext.close();
}
break;
default:
}
switch (newState) {
case OPENING_STATE:
willOpen();
continue call;
case LOADING_STATE:
willLoad();
continue call;
case STARTING_STATE:
willStart();
continue call;
case STOPPING_STATE:
willStop();
continue call;
case UNLOADING_STATE:
willUnload();
continue call;
case CLOSING_STATE:
willClose();
continue call;
default:
break call;
}
}
} while (true);
}
protected void willOpen() {
final TierContext tierContext = tierContext();
if (tierContext != null) {
tierContext.willOpen();
}
}
protected void didOpen() {
final TierContext tierContext = tierContext();
if (tierContext != null) {
tierContext.didOpen();
}
}
protected void willLoad() {
final TierContext tierContext = tierContext();
if (tierContext != null) {
tierContext.willLoad();
}
}
protected void didLoad() {
final TierContext tierContext = tierContext();
if (tierContext != null) {
tierContext.didLoad();
}
}
protected void willStart() {
final TierContext tierContext = tierContext();
if (tierContext != null) {
tierContext.willStart();
}
}
protected void didStart() {
final TierContext tierContext = tierContext();
if (tierContext != null) {
tierContext.didStart();
}
}
protected void willStop() {
final TierContext tierContext = tierContext();
if (tierContext != null) {
tierContext.willStop();
}
}
protected void didStop() {
final TierContext tierContext = tierContext();
if (tierContext != null) {
tierContext.didStop();
}
}
protected void willUnload() {
final TierContext tierContext = tierContext();
if (tierContext != null) {
tierContext.willUnload();
}
}
protected void didUnload() {
final TierContext tierContext = tierContext();
if (tierContext != null) {
tierContext.didUnload();
}
}
protected void willClose() {
final TierContext tierContext = tierContext();
if (tierContext != null) {
tierContext.willClose();
}
}
@Override
public void didClose() {
}
@Override
public void didFail(Throwable error) {
}
protected static final int STATE_MASK = 0xf;
protected static final int CLOSED_STATE = 0;
protected static final int CLOSING_STATE = 1;
protected static final int UNLOADING_STATE = 2;
protected static final int STOPPING_STATE = 3;
protected static final int RECOVERING_STATE = 4;
protected static final int FAILING_STATE = 5;
protected static final int FAILED_STATE = 6;
protected static final int OPENING_STATE = 7;
protected static final int OPENED_STATE = 8;
protected static final int LOADING_STATE = 9;
protected static final int LOADED_STATE = 10;
protected static final int STARTING_STATE = 11;
protected static final int STARTED_STATE = 12;
protected static final int PHASE_SHIFT = 4;
protected static final int PHASE_MASK = 0xf << PHASE_SHIFT;
protected static final int CLOSED_PHASE = 0;
protected static final int OPENED_PHASE = 1;
protected static final int LOADED_PHASE = 2;
protected static final int STARTED_PHASE = 3;
protected static final AtomicIntegerFieldUpdater STATUS =
AtomicIntegerFieldUpdater.newUpdater(AbstractTierBinding.class, "status");
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy