swim.system.AbstractTierBinding Maven / Gradle / Ivy
The newest version!
// Copyright 2015-2024 Nstream, 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.system;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
public abstract class AbstractTierBinding extends AbstractWarpRef implements TierBinding {
protected volatile int status;
public AbstractTierBinding() {
this.status = 0;
}
@Override
public abstract TierContext tierContext();
@Override
public boolean isClosed() {
final int state = (AbstractTierBinding.STATUS.get(this) & AbstractTierBinding.STATE_MASK);
return state == AbstractTierBinding.CLOSED_STATE;
}
@Override
public boolean isOpened() {
final int state = (AbstractTierBinding.STATUS.get(this) & AbstractTierBinding.STATE_MASK);
return state >= AbstractTierBinding.OPENED_STATE;
}
@Override
public boolean isLoaded() {
final int state = (AbstractTierBinding.STATUS.get(this) & AbstractTierBinding.STATE_MASK);
return state >= AbstractTierBinding.LOADED_STATE;
}
@Override
public boolean isStarted() {
final int state = (AbstractTierBinding.STATUS.get(this) & AbstractTierBinding.STATE_MASK);
return state == AbstractTierBinding.STARTED_STATE;
}
protected void activate(TierBinding childTier) {
final int state = AbstractTierBinding.STATUS.get(this) & AbstractTierBinding.STATE_MASK;
if (state >= AbstractTierBinding.STARTING_STATE) {
childTier.start();
} else if (state >= AbstractTierBinding.LOADING_STATE) {
childTier.load();
} else if (state >= AbstractTierBinding.OPENING_STATE) {
childTier.open();
}
}
@Override
public void open() {
int oldStatus;
int newStatus;
int oldState;
int newState;
int oldPhase;
final int newPhase = AbstractTierBinding.OPENED_PHASE;
do {
oldStatus = AbstractTierBinding.STATUS.get(this);
oldState = oldStatus & AbstractTierBinding.STATE_MASK;
oldPhase = (oldStatus & AbstractTierBinding.PHASE_MASK) >>> AbstractTierBinding.PHASE_SHIFT;
if (newPhase > oldPhase) {
if (oldState == AbstractTierBinding.CLOSED_STATE) {
newState = AbstractTierBinding.OPENING_STATE;
} else {
newState = oldState;
}
newStatus = newState & AbstractTierBinding.STATE_MASK | (newPhase << AbstractTierBinding.PHASE_SHIFT) & AbstractTierBinding.PHASE_MASK;
} else {
newState = oldState;
newStatus = oldStatus;
break;
}
} while (oldStatus != newStatus && !AbstractTierBinding.STATUS.compareAndSet(this, oldStatus, newStatus));
if (oldState != newState) {
if (newState == AbstractTierBinding.OPENING_STATE) {
this.willOpen();
this.convergeState();
}
}
}
@Override
public void load() {
int oldStatus;
int newStatus;
int oldState;
int newState;
int oldPhase;
final int newPhase = AbstractTierBinding.LOADED_PHASE;
do {
oldStatus = AbstractTierBinding.STATUS.get(this);
oldState = oldStatus & AbstractTierBinding.STATE_MASK;
oldPhase = (oldStatus & AbstractTierBinding.PHASE_MASK) >>> AbstractTierBinding.PHASE_SHIFT;
if (newPhase > oldPhase) {
if (oldState == AbstractTierBinding.OPENED_STATE) {
newState = AbstractTierBinding.LOADING_STATE;
} else if (oldState == AbstractTierBinding.CLOSED_STATE) {
newState = AbstractTierBinding.OPENING_STATE;
} else {
newState = oldState;
}
newStatus = newState & AbstractTierBinding.STATE_MASK | (newPhase << AbstractTierBinding.PHASE_SHIFT) & AbstractTierBinding.PHASE_MASK;
} else {
newState = oldState;
newStatus = oldStatus;
break;
}
} while (oldStatus != newStatus && !AbstractTierBinding.STATUS.compareAndSet(this, oldStatus, newStatus));
if (oldState != newState) {
if (newState == AbstractTierBinding.LOADING_STATE) {
this.willLoad();
this.convergeState();
} else if (newState == AbstractTierBinding.OPENING_STATE) {
this.willOpen();
this.convergeState();
}
}
}
@Override
public void start() {
int oldStatus;
int newStatus;
int oldState;
int newState;
int oldPhase;
final int newPhase = AbstractTierBinding.STARTED_PHASE;
do {
oldStatus = AbstractTierBinding.STATUS.get(this);
oldState = oldStatus & AbstractTierBinding.STATE_MASK;
oldPhase = (oldStatus & PHASE_MASK) >>> AbstractTierBinding.PHASE_SHIFT;
if (newPhase > oldPhase) {
if (oldState == AbstractTierBinding.LOADED_STATE) {
newState = AbstractTierBinding.STARTING_STATE;
} else if (oldState == AbstractTierBinding.OPENED_STATE) {
newState = AbstractTierBinding.LOADING_STATE;
} else if (oldState == AbstractTierBinding.CLOSED_STATE) {
newState = AbstractTierBinding.OPENING_STATE;
} else {
newState = oldState;
}
newStatus = newState & AbstractTierBinding.STATE_MASK | (newPhase << AbstractTierBinding.PHASE_SHIFT) & PHASE_MASK;
} else {
newState = oldState;
newStatus = oldStatus;
break;
}
} while (oldStatus != newStatus && !AbstractTierBinding.STATUS.compareAndSet(this, oldStatus, newStatus));
if (oldState != newState) {
if (newState == AbstractTierBinding.STARTING_STATE) {
this.willStart();
this.convergeState();
} else if (newState == AbstractTierBinding.LOADING_STATE) {
this.willLoad();
this.convergeState();
} else if (newState == AbstractTierBinding.OPENING_STATE) {
this.willOpen();
this.convergeState();
}
}
}
@Override
public void stop() {
int oldStatus;
int newStatus;
int oldState;
int newState;
int oldPhase;
final int newPhase = AbstractTierBinding.LOADED_PHASE;
do {
oldStatus = AbstractTierBinding.STATUS.get(this);
oldState = oldStatus & AbstractTierBinding.STATE_MASK;
oldPhase = (oldStatus & PHASE_MASK) >>> AbstractTierBinding.PHASE_SHIFT;
if (newPhase < oldPhase) {
if (oldState == AbstractTierBinding.STARTED_STATE) {
newState = AbstractTierBinding.STOPPING_STATE;
} else {
newState = oldState;
}
newStatus = newState & AbstractTierBinding.STATE_MASK | (newPhase << AbstractTierBinding.PHASE_SHIFT) & PHASE_MASK;
} else {
newState = oldState;
newStatus = oldStatus;
break;
}
} while (oldStatus != newStatus && !AbstractTierBinding.STATUS.compareAndSet(this, oldStatus, newStatus));
if (oldState != newState) {
if (newState == AbstractTierBinding.STOPPING_STATE) {
this.willStop();
this.convergeState();
}
}
}
@Override
public void unload() {
int oldStatus;
int newStatus;
int oldState;
int newState;
int oldPhase;
final int newPhase = AbstractTierBinding.OPENED_PHASE;
do {
oldStatus = AbstractTierBinding.STATUS.get(this);
oldState = oldStatus & AbstractTierBinding.STATE_MASK;
oldPhase = (oldStatus & PHASE_MASK) >>> AbstractTierBinding.PHASE_SHIFT;
if (newPhase < oldPhase) {
if (oldState == AbstractTierBinding.LOADED_STATE) {
newState = AbstractTierBinding.UNLOADING_STATE;
} else if (oldState == AbstractTierBinding.STARTED_STATE) {
newState = AbstractTierBinding.STOPPING_STATE;
} else {
newState = oldState;
}
newStatus = newState & AbstractTierBinding.STATE_MASK | (newPhase << AbstractTierBinding.PHASE_SHIFT) & PHASE_MASK;
} else {
newState = oldState;
newStatus = oldStatus;
break;
}
} while (oldStatus != newStatus && !AbstractTierBinding.STATUS.compareAndSet(this, oldStatus, newStatus));
if (oldState != newState) {
if (newState == AbstractTierBinding.UNLOADING_STATE) {
this.willUnload();
this.convergeState();
} else if (newState == AbstractTierBinding.STOPPING_STATE) {
this.willStop();
this.convergeState();
}
}
}
@Override
public void close() {
int oldStatus;
int newStatus;
int oldState;
int newState;
int oldPhase;
final int newPhase = AbstractTierBinding.CLOSED_PHASE;
do {
oldStatus = AbstractTierBinding.STATUS.get(this);
oldState = oldStatus & AbstractTierBinding.STATE_MASK;
oldPhase = (oldStatus & PHASE_MASK) >>> AbstractTierBinding.PHASE_SHIFT;
if (newPhase < oldPhase) {
if (oldState == AbstractTierBinding.OPENED_STATE) {
newState = AbstractTierBinding.CLOSING_STATE;
} else if (oldState == AbstractTierBinding.LOADED_STATE) {
newState = AbstractTierBinding.UNLOADING_STATE;
} else if (oldState == AbstractTierBinding.STARTED_STATE) {
newState = AbstractTierBinding.STOPPING_STATE;
} else {
newState = oldState;
}
newStatus = newState & AbstractTierBinding.STATE_MASK | (newPhase << AbstractTierBinding.PHASE_SHIFT) & PHASE_MASK;
} else {
newState = oldState;
newStatus = oldStatus;
break;
}
} while (oldStatus != newStatus && !AbstractTierBinding.STATUS.compareAndSet(this, oldStatus, newStatus));
if (oldState != newState) {
if (newState == AbstractTierBinding.CLOSING_STATE) {
this.willClose();
this.convergeState();
} else if (newState == AbstractTierBinding.UNLOADING_STATE) {
this.willUnload();
this.convergeState();
} else if (newState == AbstractTierBinding.STOPPING_STATE) {
this.willStop();
this.convergeState();
}
}
}
void convergeState() {
call: do {
int oldStatus;
int newStatus;
int oldState;
int newState;
loop: do {
oldStatus = AbstractTierBinding.STATUS.get(this);
oldState = oldStatus & AbstractTierBinding.STATE_MASK;
final int phase = (oldStatus & PHASE_MASK) >>> AbstractTierBinding.PHASE_SHIFT;
switch (oldState) {
case AbstractTierBinding.OPENING_STATE:
newState = phase > AbstractTierBinding.OPENED_PHASE ? AbstractTierBinding.LOADING_STATE : phase < AbstractTierBinding.OPENED_PHASE ? AbstractTierBinding.CLOSING_STATE : AbstractTierBinding.OPENED_STATE;
break;
case AbstractTierBinding.LOADING_STATE:
newState = phase > AbstractTierBinding.LOADED_PHASE ? AbstractTierBinding.STARTING_STATE : phase < AbstractTierBinding.LOADED_PHASE ? AbstractTierBinding.UNLOADING_STATE : AbstractTierBinding.LOADED_STATE;
break;
case AbstractTierBinding.STARTING_STATE:
newState = phase < AbstractTierBinding.STARTED_PHASE ? AbstractTierBinding.STOPPING_STATE : AbstractTierBinding.STARTED_STATE;
break;
case AbstractTierBinding.STOPPING_STATE:
newState = phase < AbstractTierBinding.LOADED_PHASE ? AbstractTierBinding.UNLOADING_STATE : phase > AbstractTierBinding.LOADED_PHASE ? AbstractTierBinding.STARTING_STATE : AbstractTierBinding.LOADED_STATE;
break;
case AbstractTierBinding.UNLOADING_STATE:
newState = phase < AbstractTierBinding.OPENED_PHASE ? AbstractTierBinding.CLOSING_STATE : phase > AbstractTierBinding.OPENED_PHASE ? AbstractTierBinding.LOADING_STATE : AbstractTierBinding.OPENED_STATE;
break;
case AbstractTierBinding.CLOSING_STATE:
newState = phase > AbstractTierBinding.CLOSED_PHASE ? AbstractTierBinding.OPENING_STATE : AbstractTierBinding.CLOSED_STATE;
break;
default:
newState = oldState;
newStatus = oldStatus;
break loop;
}
newStatus = oldStatus & ~AbstractTierBinding.STATE_MASK | newState & AbstractTierBinding.STATE_MASK;
} while (oldStatus != newStatus && !AbstractTierBinding.STATUS.compareAndSet(this, oldStatus, newStatus));
if (oldState != newState) {
switch (oldState) {
case AbstractTierBinding.OPENING_STATE:
this.didOpen();
break;
case AbstractTierBinding.LOADING_STATE:
this.didLoad();
break;
case AbstractTierBinding.STARTING_STATE:
this.didStart();
synchronized (this) {
this.notifyAll();
}
break;
case AbstractTierBinding.STOPPING_STATE:
this.didStop();
synchronized (this) {
this.notifyAll();
}
break;
case AbstractTierBinding.UNLOADING_STATE:
this.didUnload();
break;
case AbstractTierBinding.CLOSING_STATE:
final TierContext tierContext = this.tierContext();
if (tierContext != null) {
tierContext.close();
}
break;
default:
}
switch (newState) {
case AbstractTierBinding.OPENING_STATE:
this.willOpen();
continue call;
case AbstractTierBinding.LOADING_STATE:
this.willLoad();
continue call;
case AbstractTierBinding.STARTING_STATE:
this.willStart();
continue call;
case AbstractTierBinding.STOPPING_STATE:
this.willStop();
continue call;
case AbstractTierBinding.UNLOADING_STATE:
this.willUnload();
continue call;
case AbstractTierBinding.CLOSING_STATE:
this.willClose();
continue call;
default:
break call;
}
}
} while (true);
}
public void awaitStart() {
do {
synchronized (this) {
final int state = (AbstractTierBinding.STATUS.get(this) & AbstractTierBinding.STATE_MASK);
if (state == AbstractTierBinding.STARTED_STATE) {
break;
} else {
try {
this.wait(100);
} catch (InterruptedException e) {
break;
}
}
}
} while (true);
}
protected void willOpen() {
final TierContext tierContext = this.tierContext();
if (tierContext != null) {
tierContext.willOpen();
}
}
protected void didOpen() {
final TierContext tierContext = this.tierContext();
if (tierContext != null) {
tierContext.didOpen();
}
}
protected void willLoad() {
final TierContext tierContext = this.tierContext();
if (tierContext != null) {
tierContext.willLoad();
}
}
protected void didLoad() {
final TierContext tierContext = this.tierContext();
if (tierContext != null) {
tierContext.didLoad();
}
}
protected void willStart() {
final TierContext tierContext = this.tierContext();
if (tierContext != null) {
tierContext.willStart();
}
}
protected void didStart() {
final TierContext tierContext = this.tierContext();
if (tierContext != null) {
tierContext.didStart();
}
}
protected void willStop() {
final TierContext tierContext = this.tierContext();
if (tierContext != null) {
tierContext.willStop();
}
}
protected void didStop() {
final TierContext tierContext = this.tierContext();
if (tierContext != null) {
tierContext.didStop();
}
}
protected void willUnload() {
final TierContext tierContext = this.tierContext();
if (tierContext != null) {
tierContext.willUnload();
}
}
protected void didUnload() {
final TierContext tierContext = this.tierContext();
if (tierContext != null) {
tierContext.didUnload();
}
}
protected void willClose() {
final TierContext tierContext = this.tierContext();
if (tierContext != null) {
tierContext.willClose();
}
}
@Override
public void didClose() {
// hook
}
@Override
public void didFail(Throwable error) {
error.printStackTrace();
}
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 << AbstractTierBinding.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