package com.linkedin.databus.core;
/*
*
* Copyright 2013 LinkedIn Corp. All rights reserved
*
* 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.
*
*/
import org.apache.log4j.Logger;
import com.linkedin.databus2.core.BackoffTimer;
import com.linkedin.databus2.core.BackoffTimerStaticConfig;
public class DatabusComponentStatus
{
public enum Status
{
INITIALIZING (0),
RUNNING(100),
PAUSED(200),
ERROR_RETRY(300),
SUSPENDED_ON_ERROR(400),
SHUTDOWN(1000);
private final int _code;
Status(int code)
{
_code = code;
}
public int getCode()
{
return _code;
}
}
public static final String INITIALIZING_MESSAGE = "The databus component is initializing...";
public static final String RUNNING_MESSAGE = "The databus component is running normally.";
public static final String PAUSED_MESSAGE = "The databus component is paused by the administrator.";
public static final String SHUTDOWN_MESSAGE = "The databus component is being shutdown by the administrator...";
protected final Logger _log;
private final String _componentName;
private BackoffTimer _retriesCounter;
private Status _status;
private String _message;
private volatile long _lastStartTime;
public DatabusComponentStatus(String componentName,
Status status, String detailedMessage,
BackoffTimer errorRetriesCounter)
{
_log = Logger.getLogger(DatabusComponentStatus.class.getName() + "_" + componentName);
_componentName = componentName;
_status = status;
_message = detailedMessage;
_retriesCounter = errorRetriesCounter;
_lastStartTime = -1;
}
public DatabusComponentStatus(String componentName,
Status status, String detailedMessage,
BackoffTimerStaticConfig errorRetriesConf)
{
this(componentName, status, detailedMessage,
new BackoffTimer(componentName + ".errorRetries", errorRetriesConf));
}
public DatabusComponentStatus(String componentName,Status status, String detailedMessage)
{
this(componentName, status, detailedMessage, BackoffTimerStaticConfig.UNLIMITED_RETRIES);
}
public DatabusComponentStatus(String componentName)
{
this(componentName, Status.INITIALIZING, INITIALIZING_MESSAGE);
}
public DatabusComponentStatus(String componentName, BackoffTimerStaticConfig errorRetriesConf)
{
this(componentName, Status.INITIALIZING, INITIALIZING_MESSAGE, errorRetriesConf);
}
/**
* @return the status
*/
public synchronized Status getStatus()
{
return _status;
}
/**
* @return the message
*/
public synchronized String getMessage()
{
return _message;
}
/**
* @return status object
*/
public synchronized DatabusComponentStatus getStatusSnapshot()
{
return new DatabusComponentStatus(_componentName, _status, _message, _retriesCounter);
}
/**
* @return boolean
*/
public synchronized boolean isRunningStatus()
{
return (Status.RUNNING == _status);
}
/**
* @return boolean
*/
public synchronized boolean isPausedStatus()
{
return (Status.PAUSED == _status || Status.SUSPENDED_ON_ERROR == _status);
}
public synchronized int getRetriesNum()
{
return _retriesCounter.getRetriesNum();
}
public synchronized int getRetriesLeft()
{
return _retriesCounter.getRemainingRetriesNum();
}
public synchronized long getLastRetrySleepMs()
{
return _retriesCounter.getCurrentSleepMs();
}
/**
* block until the status is set to 'running'
*/
public synchronized void waitForResume()
{
while (isPausedStatus())
{
try
{
_log.info("Entering into waiting state..." + _status);
wait();
_log.info("Existing waiting state with new state..." + _status);
}
catch (InterruptedException e)
{
_log.info("Interruptd while being suspended!");
}
}
}
protected synchronized void setStatus(Status status, String statusDetail)
{
// Not changing to any other status once we are shutting down
if (Status.SHUTDOWN != _status)
{
Status oldStatus = _status;
_status = status;
if (Status.PAUSED == oldStatus ||
Status.SUSPENDED_ON_ERROR == oldStatus)
{
notifyAll();
}
String newMessage = statusDetail;
_lastStartTime = -1;
switch (_status)
{
case RUNNING: _retriesCounter.reset(); _lastStartTime = System.currentTimeMillis(); break;
case ERROR_RETRY:
{
_retriesCounter.backoff();
if (Status.SUSPENDED_ON_ERROR == oldStatus || Status.ERROR_RETRY == oldStatus)
{
newMessage = _message + ";" + statusDetail;
}
break;
}
case SUSPENDED_ON_ERROR:
{
if (Status.SUSPENDED_ON_ERROR == oldStatus || Status.ERROR_RETRY == oldStatus)
{
newMessage = _message + ";" + statusDetail;
}
break;
}
case INITIALIZING: break;//NOOP
case PAUSED: break;//NOOP
case SHUTDOWN: break;//impossible
}
_message = newMessage;
}
_log.debug(status.toString() + ": " + getMessage());
}
public void start()
{
setStatus(Status.RUNNING, RUNNING_MESSAGE);
}
public void shutdown()
{
setStatus(Status.SHUTDOWN, SHUTDOWN_MESSAGE);
}
public void pause()
{
setStatus(Status.PAUSED, PAUSED_MESSAGE);
}
public void resume()
{
setStatus(Status.RUNNING, RUNNING_MESSAGE);
}
public boolean retryOnError(String message)
{
setStatus(Status.ERROR_RETRY, message);
return _retriesCounter.backoffAndSleep();
}
public boolean retryOnLastError()
{
return _retriesCounter.backoffAndSleep();
}
public void suspendOnError(Throwable error)
{
setStatus(Status.SUSPENDED_ON_ERROR, null != error ? error.toString() : "unknown error");
}
public BackoffTimer getRetriesCounter()
{
return _retriesCounter;
}
public void setRetriesCounter(BackoffTimer retriesCounter)
{
_retriesCounter = retriesCounter;
}
public long getUptimeMs()
{
long lastStart = _lastStartTime;
return (0 < lastStart) ? System.currentTimeMillis() - lastStart : 0;
}
public String getComponentName()
{
return _componentName;
}
@Override
public String toString()
{
return "DatabusComponentStatus [_componentName=" + _componentName
+ ", _retriesCounter=" + _retriesCounter + ", _status=" + _status
+ ", _message=" + _message + ", _lastStartTime=" + _lastStartTime
+ "]";
}
}