com.fasterxml.clustermate.service.store.StoresImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of clustermate-service Show documentation
Show all versions of clustermate-service Show documentation
Building blocks for ClusterMate-based services and servers.
package com.fasterxml.clustermate.service.store;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.storemate.shared.IpAndPort;
import com.fasterxml.storemate.shared.TimeMaster;
import com.fasterxml.storemate.store.StorableStore;
import com.fasterxml.storemate.store.lastaccess.LastAccessStore;
import com.fasterxml.storemate.store.lastaccess.LastAccessUpdateMethod;
import com.fasterxml.storemate.store.state.NodeStateStore;
import com.fasterxml.clustermate.api.EntryKey;
import com.fasterxml.clustermate.service.Stores;
import com.fasterxml.clustermate.service.cfg.ServiceConfig;
import com.fasterxml.clustermate.service.state.ActiveNodeState;
public abstract class StoresImpl>
extends Stores
implements com.fasterxml.storemate.shared.StartAndStoppable
{
protected final Logger LOG = LoggerFactory.getLogger(getClass());
/*
/**********************************************************************
/* Configuration
/**********************************************************************
*/
protected final TimeMaster _timeMaster;
protected final ObjectMapper _jsonMapper;
/*
/**********************************************************************
/* Stores
/**********************************************************************
*/
/**
* Separately managed {@link StorableStore} that handles actual entry
* storage details.
*/
protected final StorableStore _entryStore;
/**
* We also need a factory for converting keys, entries.
*/
protected final StoredEntryConverter _entryConverter;
// Separate Environments for last-accessed, with relatively large cache
private final NodeStateStore _nodeStore;
/*
/**********************************************************************
/* Status
/**********************************************************************
*/
/**
* Marker flag used to indicate whether this store is currently active
* and able to process things.
*/
protected final AtomicBoolean _active = new AtomicBoolean(false);
/**
* Error message used to indicate why initialization failed, if it did.
*/
protected volatile String _initProblem;
/*
/**********************************************************************
/* Basic life-cycle
/**********************************************************************
*/
public StoresImpl(ServiceConfig config, TimeMaster timeMaster, ObjectMapper jsonMapper,
StoredEntryConverter entryConverter,
StorableStore entryStore,
NodeStateStore nodeStates,
File dbEnvRoot)
{
_timeMaster = timeMaster;
_jsonMapper = jsonMapper;
_entryConverter = entryConverter;
_entryStore = entryStore;
_nodeStore = nodeStates;
}
@Override
public void start() throws IOException {
// nothing much to do here; we actually force init on construction
}
@Override
public void prepareForStop()
{
/* Nothing urgent we have to do, but let's let
* stores know in case they want to do some flushing
* ahead of time
*/
if (_nodeStore != null) {
try {
_nodeStore.prepareForStop();
} catch (Exception e) {
LOG.warn("Problems with prepareForStop() on nodeStore", e);
}
}
if (_entryStore != null) {
try {
_entryStore.prepareForStop();
} catch (Exception e) {
LOG.warn("Problems with prepareForStop() on entryStore", e);
}
}
try {
_prepareToCloseLocalStores();
} catch (Exception e) {
LOG.warn("Problems calling _prepareToCloseLocalStores()", e);
}
}
@Override
public void stop() throws IOException
{
_active.set(false);
// close node store first, more important to preserve:
if (_nodeStore == null) {
LOG.warn("Odd: Node store not open? Skipping");
} else {
LOG.info("Closing Node store...");
try {
_nodeStore.stop();
} catch (Exception e) {
LOG.error("Problems closing node store: {}", e.getMessage(), e);
}
}
// then entry metadata
if (_entryStore == null) {
LOG.warn("Odd: Entry Metadata store not open? Skipping");
} else {
LOG.info("Closing Entry metadata store...");
try {
_entryStore.stop();
} catch (Exception e) {
LOG.error("Problems closing Entry Metadata store: {}", e.getMessage(), e);
}
}
// And then possibly other local database
try {
_closeLocalStores();
} catch (Exception e) {
LOG.error("Problems calling _closeLocalStores(): {}", e.getMessage(), e);
}
LOG.info("Local stores (databases) closed");
}
protected void setInitProblem(String prob) {
_initProblem = prob;
}
/*
/**********************************************************************
/* Explicit initialization, varies for different use cases
/**********************************************************************
*/
/**
* Method called to forcibly initialize environment as configured,
* and then open it normally.
*/
public boolean initAndOpen(boolean logInfo)
{
if (!_openLocalStores(true, true, true)) {
return false;
}
_active.set(true);
return true;
}
/**
* Method called to open local stores if they exist, in read/write mode.
*/
public boolean openIfExists()
{
if (!_openLocalStores(true, false, true)) {
return false;
}
_active.set(true);
return true;
}
/**
* Method called to open local stores if they exist, and only open for reading.
*/
public boolean openForReading(boolean log)
{
if (!_openLocalStores(log, false, false)) {
return false;
}
_active.set(true);
return true;
}
/**
*
* @return True if opening succeeded; false if not; in latter case, activation
* will be considered failed
*/
protected abstract boolean _openLocalStores(boolean log, boolean allowCreate, boolean writeAccess);
protected abstract void _prepareToCloseLocalStores();
protected abstract void _closeLocalStores();
/*
/**********************************************************************
/* Simple accessors
/**********************************************************************
*/
@Override
public boolean isActive() { return _active.get(); }
@Override
public String getInitProblem() { return _initProblem; }
@Override
public StoredEntryConverter getEntryConverter() { return _entryConverter; }
@Override
public StorableStore getEntryStore() { return _entryStore; }
@Override
public NodeStateStore getNodeStore() { return _nodeStore; }
@Override
public LastAccessStore getLastAccessStore() { return null; }
}