package io.mycat.backend.jdbc;
import io.mycat.backend.HeartbeatRecorder;
import io.mycat.backend.heartbeat.DBHeartbeat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.locks.ReentrantLock;
public class JDBCHeartbeat extends DBHeartbeat{
private final ReentrantLock lock;
private final JDBCDatasource source;
private final boolean heartbeatnull;
private Long lastSendTime = System.currentTimeMillis();
private Long lastReciveTime = System.currentTimeMillis();
private static final Logger logger = LoggerFactory
.getLogger(JDBCHeartbeat.class);
public JDBCHeartbeat(JDBCDatasource source)
{
this.source = source;
lock = new ReentrantLock(false);
this.status = INIT_STATUS;
this.heartbeatSQL = source.getHostConfig().getHeartbeatSQL().trim();
this.heartbeatnull= heartbeatSQL.length()==0;
}
@Override
public void start()
{
if (this.heartbeatnull){
stop();
return;
}
lock.lock();
try
{
isStop.compareAndSet(true, false);
this.status = DBHeartbeat.OK_STATUS;
} finally
{
lock.unlock();
}
}
@Override
public void stop()
{
lock.lock();
try
{
if (isStop.compareAndSet(false, true))
{
isChecking.set(false);
}
} finally
{
lock.unlock();
}
}
@Override
public String getLastActiveTime()
{
long t = lastReciveTime;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(new Date(t));
}
@Override
public long getTimeout()
{
return 0;
}
@Override
public HeartbeatRecorder getRecorder() {
recorder.set(lastReciveTime - lastSendTime);
return recorder;
}
@Override
public void heartbeat()
{
if (isStop.get())
return;
lastSendTime = System.currentTimeMillis();
lock.lock();
try
{
isChecking.set(true);
try (Connection c = source.getConnection())
{
try (Statement s = c.createStatement())
{
s.execute(heartbeatSQL);
}
}
status = OK_STATUS;
if(logger.isDebugEnabled()){
logger.debug("JDBCHeartBeat con query sql: "+heartbeatSQL);
}
} catch (Exception ex)
{
logger.error("JDBCHeartBeat error",ex);
status = ERROR_STATUS;
} finally
{
lock.unlock();
this.isChecking.set(false);
lastReciveTime = System.currentTimeMillis();
}
}
}