Skip to content
Snippets Groups Projects
Commit f202e39c authored by Raphael GIRARDOT's avatar Raphael GIRARDOT
Browse files

attributes archiving information buffer management (TANGOARCH-838)

parent e0bd3efb
Branches
Tags
No related merge requests found
Showing
with 559 additions and 51 deletions
......@@ -7,23 +7,82 @@ public interface ApiConstants {
public static final String TDB = "TDB";
public static final String TTS = "TTS";
public static final String TTS_DEVICE_CLASS = "TimeseriesArchiver";
// ///////////////////////////////////////// //
// Java properties and environment variables //
// ///////////////////////////////////////// //
// Expected behavior:
// - Mambo gets the information from the Java property.
// - If the Java property is not set, then mambo gets the information from the environment variable.
/** Java property that indicates whether TTS is available */
public static final String TTS_AVAILABLE_PROPERTY = "ttsAvailable";
/** Environment variable that indicates whether TTS is available */
public static final String TTS_AVAILABLE_ENV = "TTS_AVAILABLE";
/** Java property that indicates the TTS host */
public static final String TTS_HOST_PROPERTY = "ttsHost";
/** Environment variable that indicates the TTS host */
public static final String TTS_HOST_ENV = "TTS_HOST";
/** Java property that indicates the TTS port */
public static final String TTS_PORT_PROPERTY = "ttsPort";
/** Environment variable that indicates the TTS port */
public static final String TTS_PORT_ENV = "TTS_PORT";
/** Java property that indicates the TTS database type */
public static final String TTS_DB_TYPE_PROPERTY = "ttsDbType";
/** Environment variable that indicates the TTS database type */
public static final String TTS_DB_TYPE_ENV = "TTS_DB_TYPE";
/** Java property that indicates the TTS database name */
public static final String TTS_NAME_PROPERTY = "ttsName";
/** Environment variable that indicates the TTS database name */
public static final String TTS_NAME_ENV = "TTS_NAME";
/** Java property that indicates the TTS database schema */
public static final String TTS_SCHEMA_PROPERTY = "ttsSchema";
/** Environment variable that indicates the TTS database schema */
public static final String TTS_SCHEMA_ENV = "TTS_SCHEMA";
/** Java property that indicates the TTS database minimum pool size */
public static final String TTS_MIN_POOL_SIZE_PROPERTY = "ttsMinPoolSize";
/** Environment variable that indicates the TTS database minimum pool size */
public static final String TTS_MIN_POOL_SIZE_ENV = "TTS_MIN_POOL_SIZE";
/** Java property that indicates the TTS database maximum pool size */
public static final String TTS_MAX_POOL_SIZE_PROPERTY = "ttsMaxPoolSize";
/** Environment variable that indicates the TTS database maximum pool size */
public static final String TTS_MAX_POOL_SIZE_ENV = "TTS_MAX_POOL_SIZE";
/** Java property that indicates the TTS connection inactivity timeout */
public static final String TTS_INACTIVITY_TIMEOUT_PROPERTY = "ttsInactivityTimeout";
/** Environment variable that indicates the TTS connection inactivity timeout */
public static final String TTS_INACTIVITY_TIMEOUT_ENV = "TTS_INACTIVITY_TIMEOUT";
/** Java property that indicates whether to buffer archiving information */
public static final String BUFFERED_ARCHIVING_INFO_PROPERTY = "bufferedArchivingInfo";
/** Environment variable that indicates whether to buffer archiving information */
public static final String BUFFERED_ARCHIVING_INFO_ENV = "BUFFERED_ARCHIVING_INFO";
/** Java property that indicates the archiving information buffer lifetime, in seconds */
public static final String ATTRIBUTE_INFO_BUFFER_LIFETIME_PROPERTY = "attributeInfoBufferLifetime";
/** Environment variable that indicates the archiving information buffer lifetime, in seconds */
public static final String ATTRIBUTE_INFO_BUFFER_LIFETIME_ENV = "ATTRIBUTE_INFO_BUFFER_LIFETIME";
/**
* Java property that indicates the maximum memory percentage at which all archiving information buffers should be
* cleaned.<br />
* If used memory goes above this percentage of maximum allowed memory <i>(Xmx in Java properties)</i>, then all
* archiving information buffers are automatically cleaned in order to free memory.
*/
public static final String BUFFER_AUTOCLEAN_MEMORY_PERCENTAGE_PROPERTY = "bufferAutoCleanMemoryPercentage";
/**
* Environment variable that indicates the maximum memory percentage at which all archiving information buffers
* should be cleaned.<br />
* If used memory goes above this percentage of maximum allowed memory <i>(Xmx in Java properties)</i>, then all
* archiving information buffers are automatically cleaned in order to free memory.
*/
public static final String BUFFER_AUTOCLEAN_MEMORY_PERCENTAGE_ENV = "BUFFER_AUTOCLEAN_MEMORY_PERCENTAGE";
}
......@@ -10,6 +10,7 @@ import fr.esrf.Tango.DevFailed;
import fr.soleil.archiving.common.api.exception.ArchivingException;
import fr.soleil.archiving.hdbtdb.api.ConfigConst;
import fr.soleil.archiving.hdbtdb.api.HdbTdbConnectionParameters;
import fr.soleil.archiving.tango.entity.Attribute;
import fr.soleil.comete.swing.util.CometeConstants;
import fr.soleil.database.connection.DataBaseParameters;
import fr.soleil.database.connection.DataBaseParameters.DataBaseType;
......@@ -222,17 +223,17 @@ public class ApiUtils implements ApiConstants {
try {
if (historic == null) {
params.setParametersFromTango(TTS_DEVICE_CLASS);
params.setHost(ApiUtils.getProperty(TTS_HOST_PROPERTY, TTS_HOST_ENV, params.getHost()));
params.setName(ApiUtils.getProperty(TTS_NAME_PROPERTY, TTS_NAME_ENV, params.getName()));
params.setHost(getProperty(TTS_HOST_PROPERTY, TTS_HOST_ENV, params.getHost()));
params.setName(getProperty(TTS_NAME_PROPERTY, TTS_NAME_ENV, params.getName()));
params.setDbType(DataBaseType.parseDataBaseType(
ApiUtils.getProperty(TTS_DB_TYPE_PROPERTY, TTS_DB_TYPE_ENV, params.getDbType().toString())));
params.setSchema(ApiUtils.getProperty(TTS_SCHEMA_PROPERTY, TTS_SCHEMA_ENV, params.getSchema()));
params.setMinPoolSize((short) ApiUtils.getIntProperty(TTS_MIN_POOL_SIZE_PROPERTY, TTS_MIN_POOL_SIZE_ENV,
getProperty(TTS_DB_TYPE_PROPERTY, TTS_DB_TYPE_ENV, params.getDbType().toString())));
params.setSchema(getProperty(TTS_SCHEMA_PROPERTY, TTS_SCHEMA_ENV, params.getSchema()));
params.setMinPoolSize((short) getIntProperty(TTS_MIN_POOL_SIZE_PROPERTY, TTS_MIN_POOL_SIZE_ENV,
params.getMinPoolSize()));
params.setMaxPoolSize((short) ApiUtils.getIntProperty(TTS_MAX_POOL_SIZE_PROPERTY, TTS_MAX_POOL_SIZE_ENV,
params.setMaxPoolSize((short) getIntProperty(TTS_MAX_POOL_SIZE_PROPERTY, TTS_MAX_POOL_SIZE_ENV,
params.getMaxPoolSize()));
params.setInactivityTimeout(ApiUtils.getIntProperty(TTS_INACTIVITY_TIMEOUT_PROPERTY,
TTS_INACTIVITY_TIMEOUT_ENV, params.getInactivityTimeout()));
params.setInactivityTimeout(getIntProperty(TTS_INACTIVITY_TIMEOUT_PROPERTY, TTS_INACTIVITY_TIMEOUT_ENV,
params.getInactivityTimeout()));
applyConfiguration(DbConnectionParameters::getUser, params::getUser, params::setUser);
applyConfiguration(DbConnectionParameters::getPassword, params::getPassword, params::setPassword);
} else if (historic.booleanValue()) {
......@@ -305,4 +306,25 @@ public class ApiUtils implements ApiConstants {
return accumulated;
}
/**
* Returns the names of some {@link Attribute}s.
*
* @param defaultValue The default value to return when <code>attributes</code> is <code>null</code>.
* @param attributes The {@link Attribute}s.
* @return A {@link String} array: the attribute names.
*/
public static String[] getAttributeNames(String[] defaultValue, Attribute... attributes) {
String[] names;
if (attributes == null) {
names = defaultValue;
} else {
names = new String[attributes.length];
int index = 0;
for (Attribute attribute : attributes) {
names[index++] = attribute == null ? null : attribute.getCompleteName();
}
}
return names;
}
}
package fr.soleil.mambo.api;
import fr.soleil.archiving.common.api.exception.ArchivingException;
/**
* {@link FunctionalInterface} for the declaration of archiving functions in lambda expressions.<br />
* Based on the idea of <a href="https://stackoverflow.com/users/45914/jason">Jason</a> found on <a href=
* "https://stackoverflow.com/questions/18198176/java-8-lambda-function-that-throws-exception">stackoverflow</a>.
*
* @param <T> The type of data the function takes as input (argument).
* @param <R> The type of data returned by the function as output.
*
* @author GIRARDOT, Jason
*/
@FunctionalInterface
public interface ArchivingFunction<T, R> {
R apply(T t) throws ArchivingException;
}
\ No newline at end of file
package fr.soleil.mambo.api.archiving;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import fr.soleil.archiving.common.api.exception.ArchivingException;
import fr.soleil.mambo.api.ApiConstants;
import fr.soleil.mambo.api.ApiUtils;
import fr.soleil.mambo.api.ArchivingFunction;
import fr.soleil.mambo.api.db.IDataBaseAcess;
import fr.soleil.mambo.data.archiving.ArchivingConfigurationAttribute;
/**
* Implementation of {@link IBufferedArchivingManagerApi}.<br />
* It uses another {@link IArchivingManagerApi} to access database.
*
* @author GIRARDOT
*/
public class BufferedArchivingManagerApi implements IBufferedArchivingManagerApi, ApiConstants {
private static final Timer TIMER = new Timer("Archiving buffer auto cleaner");
// TANGOARCH-838: 8 hours (28800s) buffer lifetime
public static final int DEFAULT_LIFETIME = 28800;
// TANGOARCH-838: 85% of maximum memory before auto cleaning buffer
public static final int DEFAULT_MAX_MEMORY_PERCENTAGE = 85;
// effective buffer lifetime
private static final long LIFETIME;
// effective maximum memory proportion before auto cleaning buffer
private static final double MAX_MEMORY_PROPORTION;
static {
// TANGOARCH-838: recover expected lifetime and maximum memory percentage
int lifetime = ApiUtils.getIntProperty(ATTRIBUTE_INFO_BUFFER_LIFETIME_PROPERTY,
ATTRIBUTE_INFO_BUFFER_LIFETIME_ENV, DEFAULT_LIFETIME);
if (lifetime < 1) {
lifetime = DEFAULT_LIFETIME;
}
LIFETIME = lifetime * 1000;
int maxMemoryPercentage = ApiUtils.getIntProperty(BUFFER_AUTOCLEAN_MEMORY_PERCENTAGE_PROPERTY,
BUFFER_AUTOCLEAN_MEMORY_PERCENTAGE_ENV, DEFAULT_MAX_MEMORY_PERCENTAGE);
if (maxMemoryPercentage < 1 || maxMemoryPercentage > 99) {
maxMemoryPercentage = DEFAULT_MAX_MEMORY_PERCENTAGE;
}
MAX_MEMORY_PROPORTION = maxMemoryPercentage / 100.0d;
}
private final IArchivingManagerApi api;
private final Map<String, ArchivingInfo> archivedMap;
private final Map<String, ArchivingModeInfo> modeMap;
/**
* Constructs a new {@link BufferedArchivingManagerApi}.
*
* @param api The {@link IArchivingManagerApi} that may access database.
*/
public BufferedArchivingManagerApi(IArchivingManagerApi api) {
this.api = api;
archivedMap = new ConcurrentHashMap<>();
modeMap = new ConcurrentHashMap<>();
// TANGOARCH-838: Try to reduce memory usage by regularly cleaning maps for too old values,
// or when there is not enough memory left
TIMER.scheduleAtFixedRate(generateTimerTask(this::checkValidities, archivedMap), 0, 1000);
TIMER.scheduleAtFixedRate(generateTimerTask(this::checkValidities, modeMap), 0, 1000);
TIMER.scheduleAtFixedRate(generateTimerTask(this::checkMemory, archivedMap), 100, 1000);
TIMER.scheduleAtFixedRate(generateTimerTask(this::checkMemory, modeMap), 100, 1000);
}
/**
* Creates a {@link TimerTask} for a method that takes an argument.
*
* @param <M> The type of argument of the method.
* @param method The method.
* @param value The argument to transmit to the method.
*
* @return A {@link TimerTask}.
*/
protected <M> TimerTask generateTimerTask(Consumer<M> method, M value) {
return new TimerTask() {
@Override
public void run() {
method.accept(value);
}
};
}
/**
* Cleans too old entries in a {@link Map} that has some {@link AInfo} as values.
*
* @param <I> The type of {@link AInfo}.
* @param infoMap The {@link Map}.
*/
protected <I extends AInfo<?>> void checkValidities(Map<String, I> infoMap) {
if (infoMap != null) {
long time = System.currentTimeMillis();
infoMap.entrySet().removeIf(entry -> (entry != null) && (entry.getValue() != null)
&& time - entry.getValue().getExtractionDate() > LIFETIME);
}
}
/**
* Cleans a {@link Map} when there is not enough memory left.
*
* @param infoMap The {@link Map} to clean.
*/
protected void checkMemory(Map<?, ?> infoMap) {
if (infoMap != null) {
MemoryMXBean mxBean = ManagementFactory.getMemoryMXBean();
MemoryUsage usage = mxBean.getHeapMemoryUsage();
long used = usage.getUsed();
long max = usage.getMax();
if (used >= max * MAX_MEMORY_PROPORTION) {
infoMap.clear();
}
}
}
/**
* Register in {@link AInfo} in a {@link Map}, if not already present, and returns the effectively registered
* {@link AInfo}.
*
* @param <I> The type of {@link AInfo}.
* @param name The attribute name.
* @param info The {@link AInfo} to register.
* @param infoMap The {@link Map}.
* @return The effectively registered {@link AInfo}.
*/
protected <I extends AInfo<?>> I addInfo(String name, I info, Map<String, I> infoMap) {
I result = info;
if ((info != null) && (name != null) && (infoMap != null)) {
I tmp = infoMap.putIfAbsent(name, info);
if (tmp != null) {
result = tmp;
}
}
return result;
}
/**
* Returns some archiving information for an attribute, reading it from buffer or database, depending on its
* lifetime.
*
* @param <O> The type of archiving information.
* @param <I> The type of {@link AInfo} that may store this archiving information.
* @param attributeName The attribute name.
* @param infoMap The {@link Map} that stores the {@link AInfo}.
* @param infoClass The {@link AInfo} class.
* @param dataClass The archiving information class.
* @param method The method that reads information in database.
* @param defaultValue The default value to return if any parameter is invalid.
* @return The archiving information.
* @throws ArchivingException If a problem occurred while reading information in database.
*/
protected <O, I extends AInfo<O>> O getArchivingData(String attributeName, Map<String, I> infoMap,
Class<I> infoClass, Class<O> dataClass, ArchivingFunction<String, O> method, O defaultValue)
throws ArchivingException {
O archivingData;
if ((method == null) || (infoMap == null) || (attributeName == null) || attributeName.trim().isEmpty()) {
archivingData = defaultValue;
} else {
String name = attributeName.toLowerCase();
I info = infoMap.get(name);
try {
if ((info == null) || System.currentTimeMillis() - info.getExtractionDate() > LIFETIME) {
Constructor<I> constructor = infoClass.getConstructor(dataClass);
if (constructor == null) {
info = null;
} else {
info = addInfo(name, constructor.newInstance(method.apply(name)), infoMap);
}
}
} catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException e) {
info = null;
}
if (info == null) {
archivingData = defaultValue;
} else {
archivingData = info.getArchivingData();
if (archivingData == null) {
archivingData = defaultValue;
}
}
}
return archivingData;
}
@Override
public int getArchiverListSize() {
return api == null ? 0 : api.getArchiverListSize();
}
@Override
public String getStatus(String attributeName) throws ArchivingException {
return api == null ? null : api.getStatus(attributeName);
}
@Override
public void archivingStart(ArchivingConfigurationAttribute... attributes) throws ArchivingException {
if (api != null) {
try {
api.archivingStart(attributes);
} finally {
cleanBuffer();
}
}
}
@Override
public void archivingStop(String... attributeNameList) throws ArchivingException {
if (api != null) {
try {
api.archivingStop(attributeNameList);
} finally {
cleanBuffer();
}
}
}
@Override
public boolean isArchived(String attributeName) throws ArchivingException {
return getArchivingData(attributeName, archivedMap, ArchivingInfo.class, Boolean.TYPE,
api == null ? null : api::isArchived, Boolean.FALSE);
}
@Override
public IDataBaseAcess getDataBase() {
return api == null ? null : api.getDataBase();
}
@Override
public boolean isFacility() {
return api == null ? false : api.isFacility();
}
@Override
public String[] getExportedArchivers() {
return api == null ? EMPTY : api.getExportedArchivers();
}
@Override
public String[] getArchivingMode(String attributeName) throws ArchivingException {
return getArchivingData(attributeName, modeMap, ArchivingModeInfo.class, String[].class,
api == null ? null : api::getArchivingMode, EMPTY);
}
@Override
public void archivingConfigure() throws ArchivingException {
if (api != null) {
api.archivingConfigure();
}
}
@Override
public void archivingConfigureWithoutArchiverListInit() throws ArchivingException {
if (api != null) {
api.archivingConfigureWithoutArchiverListInit();
}
}
@Override
public void cleanBuffer() {
archivedMap.clear();
modeMap.clear();
}
@Override
public void cleanBuffer(String... attributes) {
if (attributes != null) {
for (String attribute : attributes) {
if (attribute != null) {
String name = attribute.toLowerCase();
archivedMap.remove(name);
modeMap.remove(name);
}
}
}
}
// ///////////// //
// Inner classes //
// ///////////// //
/**
* Abstract class for some archiving information concerning an attribute.
*
* @author GIRARDOT
*/
private static abstract class AInfo<T> {
private final long extractionDate;
private final T archivingData;
public AInfo(T archivingData) {
this.archivingData = archivingData;
this.extractionDate = System.currentTimeMillis();
}
/**
* Returns when the information was obtained.
*
* @return A <code>boolean</code>.
*/
public long getExtractionDate() {
return extractionDate;
}
/**
* Returns the archiving information concerning the attribute.
*
* @return The archiving information concerning the attribute.
*/
public T getArchivingData() {
return archivingData;
}
}
/**
* A class that stores information about the archiving of an attribute, and when this information was obtained.
*
* @author GIRARDOT
*/
private static class ArchivingInfo extends AInfo<Boolean> {
public ArchivingInfo(boolean archived) {
super(Boolean.valueOf(archived));
}
}
/**
* A class that stores information about the archiving mode of an attribute, and when this information was
* obtained.
*
* @author GIRARDOT
*/
private static class ArchivingModeInfo extends AInfo<String[]> {
public ArchivingModeInfo(String... archivingMode) {
super(archivingMode);
}
}
}
package fr.soleil.mambo.api.archiving;
/**
* An {@link IArchivingManagerApi} that buffers its archiving information.
*
* @author GIRARDOT
*/
public interface IBufferedArchivingManagerApi extends IArchivingManagerApi {
/**
* Cleans all buffers.
*/
public void cleanBuffer();
/**
* Cleans the buffers for given attributes.
*
* @param attributes The attribute names.
*/
public void cleanBuffer(String... attributes);
}
......@@ -462,4 +462,5 @@ public class TTSArchivingManagerApi implements IArchivingManagerApi {
}
}
}
}
......@@ -16,9 +16,10 @@ import fr.soleil.archiving.hdbtdb.api.manager.TdbArchivingManagerApiRef;
import fr.soleil.database.connection.AbstractDataBaseConnector;
import fr.soleil.database.connection.DataBaseParameters;
import fr.soleil.mambo.Mambo;
import fr.soleil.mambo.api.ApiUtils;
import fr.soleil.mambo.api.ApiConstants;
import fr.soleil.mambo.api.ApiUtils;
import fr.soleil.mambo.api.archiving.ArchivingUtils;
import fr.soleil.mambo.api.archiving.BufferedArchivingManagerApi;
import fr.soleil.mambo.api.archiving.IArchivingManagerApi;
import fr.soleil.mambo.api.archiving.LegacyArchivingManagerApi;
import fr.soleil.mambo.api.archiving.TTSArchivingManagerApi;
......@@ -27,8 +28,9 @@ import fr.soleil.mambo.api.db.HDBDataBaseAccess;
import fr.soleil.mambo.api.db.IDataBaseAcess;
import fr.soleil.mambo.api.db.TDBDataBaseAccess;
import fr.soleil.mambo.api.db.TTSDataBaseAccess;
import fr.soleil.mambo.data.IConfiguration;
public class DbConnectionManager {
public class DbConnectionManager implements ApiConstants {
private static final Logger LOGGER = LoggerFactory.getLogger(DbConnectionManager.class);
......@@ -61,12 +63,17 @@ public class DbConnectionManager {
}
private void logTTSInformation(DataBaseParameters params) {
StringBuilder builder = new StringBuilder("TTS\n");
builder.append(DbConnectionInfo.DB_HOST).append(" : ").append(params.getHost()).append('\n');
builder.append(DbConnectionInfo.DB_NAME).append(" : ").append(params.getName()).append('\n');
builder.append(DbConnectionInfo.DB_SCHEMA).append(" : ").append(params.getSchema()).append('\n');
builder.append(DbConnectionInfo.DB_USER).append(" : ").append(params.getUser()).append('\n');
builder.append(DbConnectionInfo.DB_PASSWORD).append(" : ").append(params.getPassword()).append('\n');
StringBuilder builder = new StringBuilder(TTS);
builder.append('\n').append(DbConnectionInfo.DB_HOST).append(IConfiguration.DISPAY_SEPARATOR)
.append(params.getHost());
builder.append('\n').append(DbConnectionInfo.DB_NAME).append(IConfiguration.DISPAY_SEPARATOR)
.append(params.getName());
builder.append('\n').append(DbConnectionInfo.DB_SCHEMA).append(IConfiguration.DISPAY_SEPARATOR)
.append(params.getSchema());
builder.append('\n').append(DbConnectionInfo.DB_USER).append(IConfiguration.DISPAY_SEPARATOR)
.append(params.getUser());
builder.append('\n').append(DbConnectionInfo.DB_PASSWORD).append(IConfiguration.DISPAY_SEPARATOR)
.append(params.getPassword());
Logger tmp = LoggerFactory.getLogger(HdbTdbConnectionParameters.class);
if (tmp.isInfoEnabled() && !LOGGER.isInfoEnabled()) {
tmp.info(builder.toString());
......@@ -80,13 +87,18 @@ public class DbConnectionManager {
private void connectDataBase(final Boolean historic) throws ArchivingException {
IArchivingManagerApi manager = null;
DataBaseParameters params;
boolean bufferedArchivingInfo = ApiUtils.getBooleanProperty(BUFFERED_ARCHIVING_INFO_PROPERTY,
BUFFERED_ARCHIVING_INFO_ENV, true); // activate buffer by default
if (historic == null) {
// TTS
try {
params = ApiUtils.getDataBaseParameters(historic);
TTSDataBaseAccess ttsAccess = new TTSDataBaseAccess(params);
DbConnectionManager.ttsAccess = ttsAccess;
ttsManager = new TTSArchivingManagerApi(ttsAccess, params, ArchivingUtils.TTS_DEVICE_CLASS);
// TANGOARCH-838: buffer management.
TTSArchivingManagerApi api = new TTSArchivingManagerApi(ttsAccess, params,
ArchivingUtils.TTS_DEVICE_CLASS);
ttsManager = bufferedArchivingInfo ? new BufferedArchivingManagerApi(api) : api;
manager = ttsManager;
logTTSInformation(params);
} catch (Exception e) {
......@@ -103,7 +115,9 @@ public class DbConnectionManager {
final AbstractDataBaseConnector connector = ConnectionFactory.connect(params);
IArchivingManagerApiRef managerRef = ArchivingManagerApiRefFactory.getInstance(true, connector);
hdbAccess = new HDBDataBaseAccess((HdbArchivingManagerApiRef) managerRef, connector);
hdbManager = new LegacyArchivingManagerApi(hdbAccess, managerRef, true);
// TANGOARCH-838: buffer management.
LegacyArchivingManagerApi api = new LegacyArchivingManagerApi(hdbAccess, managerRef, true);
hdbManager = bufferedArchivingInfo ? new BufferedArchivingManagerApi(api) : api;
manager = hdbManager;
HdbTdbConnectionParameters.printHDBConnectionInfoLog();
} else {
......@@ -112,7 +126,9 @@ public class DbConnectionManager {
final AbstractDataBaseConnector connector = ConnectionFactory.connect(params);
IArchivingManagerApiRef managerRef = ArchivingManagerApiRefFactory.getInstance(false, connector);
tdbAccess = new TDBDataBaseAccess((TdbArchivingManagerApiRef) managerRef, connector);
tdbManager = new LegacyArchivingManagerApi(tdbAccess, managerRef, false);
// TANGOARCH-838: buffer management.
LegacyArchivingManagerApi api = new LegacyArchivingManagerApi(tdbAccess, managerRef, false);
tdbManager = bufferedArchivingInfo ? new BufferedArchivingManagerApi(api) : api;
manager = tdbManager;
HdbTdbConnectionParameters.printTDBConnectionInfoLog();
}
......
......@@ -17,6 +17,7 @@ import fr.soleil.mambo.api.archiving.ArchiverFactory;
import fr.soleil.mambo.api.archiving.ArchivingUtils;
import fr.soleil.mambo.api.archiving.IArchiver;
import fr.soleil.mambo.api.archiving.IArchivingManagerApi;
import fr.soleil.mambo.api.archiving.IBufferedArchivingManagerApi;
import fr.soleil.mambo.api.db.TDBDataBaseAccess;
import fr.soleil.mambo.data.archiving.ArchivingConfiguration;
import fr.soleil.mambo.data.archiving.ArchivingConfigurationAttribute;
......@@ -66,6 +67,7 @@ public class BasicArchivingManager extends DbConnectionManager implements IArchi
manager = tdbManager;
dbName = ApiConstants.TDB;
}
try {
int exceptionCounter = 1;
String exceptionMessage = ObjectUtils.EMPTY_STRING;
openConnection();
......@@ -110,6 +112,13 @@ public class BasicArchivingManager extends DbConnectionManager implements IArchi
if (exceptionCounter > 1) {
throw toThrow;
}
} finally {
// TANGOARCH-838: clean attributes buffer after stop, to force reading the information in database.
if (manager instanceof IBufferedArchivingManagerApi) {
IBufferedArchivingManagerApi bufferedManager = (IBufferedArchivingManagerApi) manager;
bufferedManager.cleanBuffer(ApiUtils.getAttributeNames(EMPTY, attributes));
}
}
} // end if ((ac != null) && (attributes != null))
}
......
......@@ -5,7 +5,9 @@ import org.slf4j.LoggerFactory;
import fr.soleil.archiving.common.api.exception.ArchivingException;
import fr.soleil.mambo.api.ApiConstants;
import fr.soleil.mambo.api.ApiUtils;
import fr.soleil.mambo.api.archiving.IArchivingManagerApi;
import fr.soleil.mambo.api.archiving.IBufferedArchivingManagerApi;
import fr.soleil.mambo.data.archiving.ArchivingConfiguration;
import fr.soleil.mambo.data.archiving.ArchivingConfigurationAttribute;
import fr.soleil.mambo.data.archiving.ArchivingConfigurationAttributes;
......@@ -50,7 +52,15 @@ public class GlobalStartArchivingManager extends BasicArchivingManager {
LOGGER.error(errorMessage);
throw new ArchivingException(errorMessage);
} else {
try {
manager.archivingStart(attributes);
} finally {
// TANGOARCH-838: clean attributes buffer after start, to force reading the information in database.
if (manager instanceof IBufferedArchivingManagerApi) {
IBufferedArchivingManagerApi bufferedManager = (IBufferedArchivingManagerApi) manager;
bufferedManager.cleanBuffer(ApiUtils.getAttributeNames(EMPTY, attributes));
}
}
}
}
}
......
......@@ -14,6 +14,7 @@ import fr.soleil.comete.tango.data.service.helper.TangoExceptionHelper;
import fr.soleil.lib.project.application.user.manager.AccountManager;
import fr.soleil.lib.project.swing.Splash;
import fr.soleil.mambo.Mambo;
import fr.soleil.mambo.api.ApiConstants;
import fr.soleil.mambo.api.db.DbConnectionParameters;
import fr.soleil.mambo.datasources.db.archiving.ArchivingManagerFactory;
import fr.soleil.mambo.datasources.db.attributes.AttributeManagerFactory;
......@@ -37,9 +38,7 @@ import fr.soleil.mambo.options.sub.SaveOptions;
import fr.soleil.mambo.tools.Messages;
import fr.soleil.mambo.tools.xmlhelpers.ac.ArchivingConfigurationXMLHelperFactory;
public class DefaultLifeCycleManager implements LifeCycleManager {
private static final String TTS = "TTS";
public class DefaultLifeCycleManager implements LifeCycleManager, ApiConstants {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultLifeCycleManager.class);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment