package org.yamcs.parameterarchive;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.yamcs.ConfigurationException;
import org.yamcs.parameter.ParameterValue;
import org.yamcs.utils.LoggingUtils;
import org.yamcs.utils.TimeEncoding;
import org.yamcs.YConfiguration;
import org.yamcs.Processor;
public class RealtimeArchiveFiller extends ArchiveFillerTask {
ScheduledThreadPoolExecutor executor=new ScheduledThreadPoolExecutor(1);
int flushInterval = 300; //seconds
final Logger log;
String processorName = "realtime";
final String yamcsInstance;
Processor realtimeProcessor;
int subscriptionId;
public RealtimeArchiveFiller(ParameterArchive parameterArchive, Map<String, Object> config) {
super(parameterArchive);
this.yamcsInstance = parameterArchive.getYamcsInstance();
log = LoggingUtils.getLogger(this.getClass(), yamcsInstance);
if(config!=null) {
parseConfig(config);
}
}
private void parseConfig(Map<String, Object> config) {
flushInterval = YConfiguration.getInt(config, "flushInterval", flushInterval);
processorName = YConfiguration.getString(config, "processorName", processorName);
}
//move the updateItems (and all processing thereafter) in the executor thread
@Override
public void updateItems(int subscriptionId, List<ParameterValue> items) {
executor.execute(()-> {
try {
super.updateItems(subscriptionId, items);
} catch(Exception e) {
log.error("Error when adding data to realtime segments", e);
}
});
}
public void flush() {
try {
for(Map.Entry<Long, Map<Integer, PGSegment>> k:pgSegments.entrySet()) {
Map <Integer, PGSegment> m = k.getValue();
long sstart = k.getKey();
log.debug("Writing to archive the segment: [{} - {})", TimeEncoding.toString(sstart), TimeEncoding.toString(SortedTimeSegment.getNextSegmentStart(sstart)));
consolidateAndWriteToArchive(m.values());
}
} catch(Exception e) {
log.error("Error when flusing data to parameter archive ", e);
}
}
void start() {
//subscribe to the realtime processor
realtimeProcessor = Processor.getInstance(yamcsInstance, processorName);
if(realtimeProcessor == null) {
throw new ConfigurationException("No processor named '"+processorName+"' in instance "+yamcsInstance);
}
subscriptionId = realtimeProcessor.getParameterRequestManager().subscribeAll(this);
executor.scheduleAtFixedRate(this::flush, flushInterval, flushInterval, TimeUnit.SECONDS);
}
void stop() {
realtimeProcessor.getParameterRequestManager().unsubscribeAll(subscriptionId);
executor.shutdown();
flush();
}
}