use of org.jumpmind.symmetric.model.ProcessInfo in project symmetric-ds by JumpMind.
the class FileSyncPullUriHandler method handle.
public void handle(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
String nodeId = ServletUtils.getParameter(req, WebConstants.NODE_ID);
if (StringUtils.isBlank(nodeId)) {
ServletUtils.sendError(res, HttpServletResponse.SC_BAD_REQUEST, "Node must be specified");
return;
} else {
log.debug("File sync pull request received from {}", nodeId);
}
IOutgoingTransport outgoingTransport = createOutgoingTransport(res.getOutputStream(), req.getHeader(WebConstants.HEADER_ACCEPT_CHARSET), engine.getConfigurationService().getSuspendIgnoreChannelLists(nodeId));
ProcessInfo processInfo = engine.getStatisticManager().newProcessInfo(new ProcessInfoKey(engine.getNodeService().findIdentityNodeId(), nodeId, ProcessType.FILE_SYNC_PULL_HANDLER));
try {
engine.getFileSyncService().sendFiles(processInfo, engine.getNodeService().findNode(nodeId, true), outgoingTransport);
Node targetNode = engine.getNodeService().findNode(nodeId, true);
if (processInfo.getBatchCount() == 0 && targetNode.isVersionGreaterThanOrEqualTo(3, 8, 0)) {
ServletUtils.sendError(res, HttpServletResponse.SC_NO_CONTENT, "No files to pull.");
} else {
res.setContentType("application/zip");
res.addHeader("Content-Disposition", "attachment; filename=\"file-sync.zip\"");
}
processInfo.setStatus(Status.OK);
} catch (RuntimeException ex) {
processInfo.setStatus(Status.ERROR);
throw ex;
} finally {
if (outgoingTransport != null) {
outgoingTransport.close();
}
}
}
use of org.jumpmind.symmetric.model.ProcessInfo in project symmetric-ds by JumpMind.
the class RouterService method insertInitialLoadEvents.
/**
* If a load has been queued up by setting the initial load enabled or
* reverse initial load enabled flags, then the router service will insert
* the reload events. This process will not run at the same time sync
* triggers is running.
*/
protected void insertInitialLoadEvents() {
ProcessInfo processInfo = engine.getStatisticManager().newProcessInfo(new ProcessInfoKey(engine.getNodeService().findIdentityNodeId(), null, ProcessType.INSERT_LOAD_EVENTS));
processInfo.setStatus(ProcessInfo.Status.PROCESSING);
try {
INodeService nodeService = engine.getNodeService();
Node identity = nodeService.findIdentity();
if (identity != null) {
boolean isClusteringEnabled = parameterService.is(ParameterConstants.CLUSTER_LOCKING_ENABLED);
NodeSecurity identitySecurity = nodeService.findNodeSecurity(identity.getNodeId(), !isClusteringEnabled);
if (engine.getParameterService().isRegistrationServer() || (identitySecurity != null && !identitySecurity.isRegistrationEnabled() && identitySecurity.getRegistrationTime() != null)) {
List<NodeSecurity> nodeSecurities = findNodesThatAreReadyForInitialLoad();
if (nodeSecurities != null && nodeSecurities.size() > 0) {
gapDetector.setFullGapAnalysis(true);
boolean reverseLoadFirst = parameterService.is(ParameterConstants.INITIAL_LOAD_REVERSE_FIRST);
boolean isInitialLoadQueued = false;
for (NodeSecurity security : nodeSecurities) {
if (engine.getTriggerRouterService().getActiveTriggerHistories().size() > 0) {
boolean thisMySecurityRecord = security.getNodeId().equals(identity.getNodeId());
boolean reverseLoadQueued = security.isRevInitialLoadEnabled();
boolean initialLoadQueued = security.isInitialLoadEnabled();
boolean registered = security.getRegistrationTime() != null;
if (thisMySecurityRecord && reverseLoadQueued && (reverseLoadFirst || !initialLoadQueued)) {
sendReverseInitialLoad(processInfo);
} else if (!thisMySecurityRecord && registered && initialLoadQueued && (!reverseLoadFirst || !reverseLoadQueued)) {
long ts = System.currentTimeMillis();
engine.getDataService().insertReloadEvents(engine.getNodeService().findNode(security.getNodeId()), false, processInfo);
isInitialLoadQueued = true;
ts = System.currentTimeMillis() - ts;
if (ts > Constants.LONG_OPERATION_THRESHOLD) {
log.warn("Inserted reload events for node {} took longer than expected. It took {} ms", security.getNodeId(), ts);
} else {
log.info("Inserted reload events for node {} in {} ms", security.getNodeId(), ts);
}
}
} else {
List<NodeGroupLink> links = engine.getConfigurationService().getNodeGroupLinksFor(parameterService.getNodeGroupId(), false);
if (links == null || links.size() == 0) {
log.warn("Could not queue up a load for {} because a node group link is NOT configured over which a load could be delivered", security.getNodeId());
} else {
log.warn("Could not queue up a load for {} because sync triggers has not yet run", security.getNodeId());
if (!syncTriggersBeforeInitialLoadAttempted) {
syncTriggersBeforeInitialLoadAttempted = true;
engine.getTriggerRouterService().syncTriggers();
}
}
}
}
if (isInitialLoadQueued) {
gapDetector.setFullGapAnalysis(true);
}
}
processTableRequestLoads(identity, processInfo);
}
}
processInfo.setStatus(ProcessInfo.Status.OK);
} catch (Exception ex) {
processInfo.setStatus(ProcessInfo.Status.ERROR);
log.error("", ex);
}
}
use of org.jumpmind.symmetric.model.ProcessInfo in project symmetric-ds by JumpMind.
the class OfflinePushService method pushToNode.
private void pushToNode(Node remote, RemoteNodeStatus status) {
Node identity = nodeService.findIdentity();
FileOutgoingTransport transport = null;
ProcessInfo processInfo = statisticManager.newProcessInfo(new ProcessInfoKey(identity.getNodeId(), status.getChannelId(), remote.getNodeId(), ProcessType.OFFLINE_PUSH));
List<OutgoingBatch> extractedBatches = null;
try {
transport = (FileOutgoingTransport) transportManager.getPushTransport(remote, identity, null, null);
extractedBatches = dataExtractorService.extract(processInfo, remote, status.getChannelId(), transport);
if (extractedBatches.size() > 0) {
log.info("Offline push data written for {} at {}", remote, transport.getOutgoingDir());
List<BatchAck> batchAcks = readAcks(extractedBatches, transport, transportManager, acknowledgeService);
status.updateOutgoingStatus(extractedBatches, batchAcks);
}
if (processInfo.getStatus() != Status.ERROR) {
processInfo.setStatus(Status.OK);
}
} catch (Exception ex) {
processInfo.setStatus(Status.ERROR);
log.error("Failed to write offline file", ex);
} finally {
transport.close();
transport.complete(processInfo.getStatus() == Status.OK);
}
}
use of org.jumpmind.symmetric.model.ProcessInfo in project symmetric-ds by JumpMind.
the class AbstractSymmetricEngine method stop.
public synchronized void stop() {
log.info("Stopping SymmetricDS externalId={} version={} database={}", new Object[] { parameterService == null ? "?" : parameterService.getExternalId(), Version.version(), symmetricDialect == null ? "?" : symmetricDialect.getName() });
if (jobManager != null) {
jobManager.stopJobs();
}
if (routerService != null) {
routerService.stop();
}
if (nodeCommunicationService != null) {
nodeCommunicationService.stop();
}
if (statisticManager != null) {
List<ProcessInfo> infos = statisticManager.getProcessInfos();
for (ProcessInfo processInfo : infos) {
Thread thread = processInfo.getThread();
if (processInfo.getStatus() != Status.OK && thread.isAlive()) {
log.info("Trying to interrupt thread '{}' ", thread.getName());
try {
thread.interrupt();
} catch (Exception e) {
log.info("Caught exception while attempting to interrupt thread", e);
}
}
}
Thread.interrupted();
}
started = false;
starting = false;
}
use of org.jumpmind.symmetric.model.ProcessInfo in project symmetric-ds by JumpMind.
the class DataGapFastDetector method beforeRouting.
public void beforeRouting() {
maxDataToSelect = parameterService.getLong(ParameterConstants.ROUTING_LARGEST_GAP_SIZE);
detectInvalidGaps = parameterService.is(ParameterConstants.ROUTING_DETECT_INVALID_GAPS);
reset();
if (isFullGapAnalysis()) {
ProcessInfo processInfo = this.statisticManager.newProcessInfo(new ProcessInfoKey(nodeService.findIdentityNodeId(), null, ProcessType.GAP_DETECT));
processInfo.setStatus(Status.QUERYING);
log.info("Full gap analysis is running");
long ts = System.currentTimeMillis();
gaps = dataService.findDataGaps();
if (detectInvalidGaps) {
fixOverlappingGaps(gaps, processInfo);
}
queryDataIdMap();
processInfo.setStatus(Status.OK);
log.info("Querying data in gaps from database took {} ms", System.currentTimeMillis() - ts);
afterRouting();
reset();
log.info("Full gap analysis is done after {} ms", System.currentTimeMillis() - ts);
} else if (gaps == null || parameterService.is(ParameterConstants.CLUSTER_LOCKING_ENABLED)) {
ProcessInfo processInfo = this.statisticManager.newProcessInfo(new ProcessInfoKey(nodeService.findIdentityNodeId(), null, ProcessType.GAP_DETECT));
processInfo.setStatus(Status.QUERYING);
gaps = dataService.findDataGaps();
if (detectInvalidGaps) {
fixOverlappingGaps(gaps, processInfo);
}
processInfo.setStatus(Status.OK);
}
}
Aggregations