use of com.unboundid.util.FixedRateBarrier in project ldapsdk by pingidentity.
the class SearchAndModRate method doToolProcessing.
/**
* Performs the actual processing for this tool. In this case, it gets a
* connection to the directory server and uses it to perform the requested
* searches.
*
* @return The result code for the processing that was performed.
*/
@Override()
@NotNull()
public ResultCode doToolProcessing() {
// variable rate data file and return.
if (sampleRateFile.isPresent()) {
try {
RateAdjustor.writeSampleVariableRateFile(sampleRateFile.getValue());
return ResultCode.SUCCESS;
} catch (final Exception e) {
Debug.debugException(e);
err("An error occurred while trying to write sample variable data " + "rate file '", sampleRateFile.getValue().getAbsolutePath(), "': ", StaticUtils.getExceptionMessage(e));
return ResultCode.LOCAL_ERROR;
}
}
// Determine the random seed to use.
final Long seed;
if (randomSeed.isPresent()) {
seed = Long.valueOf(randomSeed.getValue());
} else {
seed = null;
}
// Create value patterns for the base DN, filter, and proxied authorization
// DN.
final ValuePattern dnPattern;
try {
dnPattern = new ValuePattern(baseDN.getValue(), seed);
} catch (final ParseException pe) {
Debug.debugException(pe);
err("Unable to parse the base DN value pattern: ", pe.getMessage());
return ResultCode.PARAM_ERROR;
}
final ValuePattern filterPattern;
try {
filterPattern = new ValuePattern(filter.getValue(), seed);
} catch (final ParseException pe) {
Debug.debugException(pe);
err("Unable to parse the filter pattern: ", pe.getMessage());
return ResultCode.PARAM_ERROR;
}
final ValuePattern authzIDPattern;
if (proxyAs.isPresent()) {
try {
authzIDPattern = new ValuePattern(proxyAs.getValue(), seed);
} catch (final ParseException pe) {
Debug.debugException(pe);
err("Unable to parse the proxied authorization pattern: ", pe.getMessage());
return ResultCode.PARAM_ERROR;
}
} else {
authzIDPattern = null;
}
// Get the set of controls to include in search requests.
final ArrayList<Control> searchControls = new ArrayList<>(5);
if (searchAssertionFilter.isPresent()) {
searchControls.add(new AssertionRequestControl(searchAssertionFilter.getValue()));
}
if (searchControl.isPresent()) {
searchControls.addAll(searchControl.getValues());
}
// Get the set of controls to include in modify requests.
final ArrayList<Control> modifyControls = new ArrayList<>(5);
if (modifyAssertionFilter.isPresent()) {
modifyControls.add(new AssertionRequestControl(modifyAssertionFilter.getValue()));
}
if (permissiveModify.isPresent()) {
modifyControls.add(new PermissiveModifyRequestControl());
}
if (preReadAttribute.isPresent()) {
final List<String> attrList = preReadAttribute.getValues();
final String[] attrArray = new String[attrList.size()];
attrList.toArray(attrArray);
modifyControls.add(new PreReadRequestControl(attrArray));
}
if (postReadAttribute.isPresent()) {
final List<String> attrList = postReadAttribute.getValues();
final String[] attrArray = new String[attrList.size()];
attrList.toArray(attrArray);
modifyControls.add(new PostReadRequestControl(attrArray));
}
if (modifyControl.isPresent()) {
modifyControls.addAll(modifyControl.getValues());
}
// Get the attributes to return.
final String[] returnAttrs;
if (returnAttributes.isPresent()) {
final List<String> attrList = returnAttributes.getValues();
returnAttrs = new String[attrList.size()];
attrList.toArray(returnAttrs);
} else {
returnAttrs = StaticUtils.NO_STRINGS;
}
// Get the names of the attributes to modify.
final String[] modAttrs = new String[modifyAttributes.getValues().size()];
modifyAttributes.getValues().toArray(modAttrs);
// Get the character set as a byte array.
final byte[] charSet = StaticUtils.getBytes(characterSet.getValue());
// If the --ratePerSecond option was specified, then limit the rate
// accordingly.
FixedRateBarrier fixedRateBarrier = null;
if (ratePerSecond.isPresent() || variableRateData.isPresent()) {
// We might not have a rate per second if --variableRateData is specified.
// The rate typically doesn't matter except when we have warm-up
// intervals. In this case, we'll run at the max rate.
final int intervalSeconds = collectionInterval.getValue();
final int ratePerInterval = (ratePerSecond.getValue() == null) ? Integer.MAX_VALUE : ratePerSecond.getValue() * intervalSeconds;
fixedRateBarrier = new FixedRateBarrier(1000L * intervalSeconds, ratePerInterval);
}
// If --variableRateData was specified, then initialize a RateAdjustor.
RateAdjustor rateAdjustor = null;
if (variableRateData.isPresent()) {
try {
rateAdjustor = RateAdjustor.newInstance(fixedRateBarrier, ratePerSecond.getValue(), variableRateData.getValue());
} catch (final IOException | IllegalArgumentException e) {
Debug.debugException(e);
err("Initializing the variable rates failed: " + e.getMessage());
return ResultCode.PARAM_ERROR;
}
}
// Determine whether to include timestamps in the output and if so what
// format should be used for them.
final boolean includeTimestamp;
final String timeFormat;
if (timestampFormat.getValue().equalsIgnoreCase("with-date")) {
includeTimestamp = true;
timeFormat = "dd/MM/yyyy HH:mm:ss";
} else if (timestampFormat.getValue().equalsIgnoreCase("without-date")) {
includeTimestamp = true;
timeFormat = "HH:mm:ss";
} else {
includeTimestamp = false;
timeFormat = null;
}
// Determine whether any warm-up intervals should be run.
final long totalIntervals;
final boolean warmUp;
int remainingWarmUpIntervals = warmUpIntervals.getValue();
if (remainingWarmUpIntervals > 0) {
warmUp = true;
totalIntervals = 0L + numIntervals.getValue() + remainingWarmUpIntervals;
} else {
warmUp = true;
totalIntervals = 0L + numIntervals.getValue();
}
// Create the table that will be used to format the output.
final OutputFormat outputFormat;
if (csvFormat.isPresent()) {
outputFormat = OutputFormat.CSV;
} else {
outputFormat = OutputFormat.COLUMNS;
}
final ColumnFormatter formatter = new ColumnFormatter(includeTimestamp, timeFormat, outputFormat, " ", new FormattableColumn(12, HorizontalAlignment.RIGHT, "Recent", "Searches/Sec"), new FormattableColumn(12, HorizontalAlignment.RIGHT, "Recent", "Srch Dur ms"), new FormattableColumn(12, HorizontalAlignment.RIGHT, "Recent", "Mods/Sec"), new FormattableColumn(12, HorizontalAlignment.RIGHT, "Recent", "Mod Dur ms"), new FormattableColumn(12, HorizontalAlignment.RIGHT, "Recent", "Errors/Sec"), new FormattableColumn(12, HorizontalAlignment.RIGHT, "Overall", "Searches/Sec"), new FormattableColumn(12, HorizontalAlignment.RIGHT, "Overall", "Srch Dur ms"), new FormattableColumn(12, HorizontalAlignment.RIGHT, "Overall", "Mods/Sec"), new FormattableColumn(12, HorizontalAlignment.RIGHT, "Overall", "Mod Dur ms"));
// Create values to use for statistics collection.
final AtomicLong searchCounter = new AtomicLong(0L);
final AtomicLong errorCounter = new AtomicLong(0L);
final AtomicLong modCounter = new AtomicLong(0L);
final AtomicLong modDurations = new AtomicLong(0L);
final AtomicLong searchDurations = new AtomicLong(0L);
final ResultCodeCounter rcCounter = new ResultCodeCounter();
// Determine the length of each interval in milliseconds.
final long intervalMillis = 1000L * collectionInterval.getValue();
// Create the threads to use for the searches.
final Random random = new Random();
final CyclicBarrier barrier = new CyclicBarrier(numThreads.getValue() + 1);
final SearchAndModRateThread[] threads = new SearchAndModRateThread[numThreads.getValue()];
for (int i = 0; i < threads.length; i++) {
final LDAPConnection connection;
try {
connection = getConnection();
} catch (final LDAPException le) {
Debug.debugException(le);
err("Unable to connect to the directory server: ", StaticUtils.getExceptionMessage(le));
return le.getResultCode();
}
threads[i] = new SearchAndModRateThread(this, i, connection, dnPattern, scopeArg.getValue(), filterPattern, returnAttrs, modAttrs, valueLength.getValue(), charSet, authzIDPattern, simplePageSize.getValue(), searchControls, modifyControls, iterationsBeforeReconnect.getValue(), random.nextLong(), runningThreads, barrier, searchCounter, modCounter, searchDurations, modDurations, errorCounter, rcCounter, fixedRateBarrier);
threads[i].start();
}
// Display the table header.
for (final String headerLine : formatter.getHeaderLines(true)) {
out(headerLine);
}
// which case, we'll start it after the warm-up is complete.
if ((rateAdjustor != null) && (remainingWarmUpIntervals <= 0)) {
rateAdjustor.start();
}
// Indicate that the threads can start running.
try {
barrier.await();
} catch (final Exception e) {
Debug.debugException(e);
}
long overallStartTime = System.nanoTime();
long nextIntervalStartTime = System.currentTimeMillis() + intervalMillis;
boolean setOverallStartTime = false;
long lastSearchDuration = 0L;
long lastModDuration = 0L;
long lastNumErrors = 0L;
long lastNumSearches = 0L;
long lastNumMods = 0L;
long lastEndTime = System.nanoTime();
for (long i = 0; i < totalIntervals; i++) {
if (rateAdjustor != null) {
if (!rateAdjustor.isAlive()) {
out("All of the rates in " + variableRateData.getValue().getName() + " have been completed.");
break;
}
}
final long startTimeMillis = System.currentTimeMillis();
final long sleepTimeMillis = nextIntervalStartTime - startTimeMillis;
nextIntervalStartTime += intervalMillis;
if (sleepTimeMillis > 0) {
sleeper.sleep(sleepTimeMillis);
}
if (stopRequested.get()) {
break;
}
final long endTime = System.nanoTime();
final long intervalDuration = endTime - lastEndTime;
final long numSearches;
final long numMods;
final long numErrors;
final long totalSearchDuration;
final long totalModDuration;
if (warmUp && (remainingWarmUpIntervals > 0)) {
numSearches = searchCounter.getAndSet(0L);
numMods = modCounter.getAndSet(0L);
numErrors = errorCounter.getAndSet(0L);
totalSearchDuration = searchDurations.getAndSet(0L);
totalModDuration = modDurations.getAndSet(0L);
} else {
numSearches = searchCounter.get();
numMods = modCounter.get();
numErrors = errorCounter.get();
totalSearchDuration = searchDurations.get();
totalModDuration = modDurations.get();
}
final long recentNumSearches = numSearches - lastNumSearches;
final long recentNumMods = numMods - lastNumMods;
final long recentNumErrors = numErrors - lastNumErrors;
final long recentSearchDuration = totalSearchDuration - lastSearchDuration;
final long recentModDuration = totalModDuration - lastModDuration;
final double numSeconds = intervalDuration / 1_000_000_000.0d;
final double recentSearchRate = recentNumSearches / numSeconds;
final double recentModRate = recentNumMods / numSeconds;
final double recentErrorRate = recentNumErrors / numSeconds;
final double recentAvgSearchDuration;
if (recentNumSearches > 0L) {
recentAvgSearchDuration = 1.0d * recentSearchDuration / recentNumSearches / 1_000_000;
} else {
recentAvgSearchDuration = 0.0d;
}
final double recentAvgModDuration;
if (recentNumMods > 0L) {
recentAvgModDuration = 1.0d * recentModDuration / recentNumMods / 1_000_000;
} else {
recentAvgModDuration = 0.0d;
}
if (warmUp && (remainingWarmUpIntervals > 0)) {
out(formatter.formatRow(recentSearchRate, recentAvgSearchDuration, recentModRate, recentAvgModDuration, recentErrorRate, "warming up", "warming up", "warming up", "warming up"));
remainingWarmUpIntervals--;
if (remainingWarmUpIntervals == 0) {
out("Warm-up completed. Beginning overall statistics collection.");
setOverallStartTime = true;
if (rateAdjustor != null) {
rateAdjustor.start();
}
}
} else {
if (setOverallStartTime) {
overallStartTime = lastEndTime;
setOverallStartTime = false;
}
final double numOverallSeconds = (endTime - overallStartTime) / 1_000_000_000.0d;
final double overallSearchRate = numSearches / numOverallSeconds;
final double overallModRate = numMods / numOverallSeconds;
final double overallAvgSearchDuration;
if (numSearches > 0L) {
overallAvgSearchDuration = 1.0d * totalSearchDuration / numSearches / 1_000_000;
} else {
overallAvgSearchDuration = 0.0d;
}
final double overallAvgModDuration;
if (numMods > 0L) {
overallAvgModDuration = 1.0d * totalModDuration / numMods / 1_000_000;
} else {
overallAvgModDuration = 0.0d;
}
out(formatter.formatRow(recentSearchRate, recentAvgSearchDuration, recentModRate, recentAvgModDuration, recentErrorRate, overallSearchRate, overallAvgSearchDuration, overallModRate, overallAvgModDuration));
lastNumSearches = numSearches;
lastNumMods = numMods;
lastNumErrors = numErrors;
lastSearchDuration = totalSearchDuration;
lastModDuration = totalModDuration;
}
final List<ObjectPair<ResultCode, Long>> rcCounts = rcCounter.getCounts(true);
if ((!suppressErrors.isPresent()) && (!rcCounts.isEmpty())) {
err("\tError Results:");
for (final ObjectPair<ResultCode, Long> p : rcCounts) {
err("\t", p.getFirst().getName(), ": ", p.getSecond());
}
}
lastEndTime = endTime;
}
// Shut down the RateAdjustor if we have one.
if (rateAdjustor != null) {
rateAdjustor.shutDown();
}
// Stop all of the threads.
ResultCode resultCode = ResultCode.SUCCESS;
for (final SearchAndModRateThread t : threads) {
final ResultCode r = t.stopRunning();
if (resultCode == ResultCode.SUCCESS) {
resultCode = r;
}
}
return resultCode;
}
use of com.unboundid.util.FixedRateBarrier in project ldapsdk by pingidentity.
the class ParallelUpdate method doToolProcessing.
/**
* {@inheritDoc}
*/
@Override()
@NotNull()
public ResultCode doToolProcessing() {
// Create the sets of controls to include in each type of request.
final Control[] addControls;
final Control[] deleteControls;
final Control[] modifyControls;
final Control[] modifyDNControls;
try {
final List<Control> addControlList = new ArrayList<>();
final List<Control> deleteControlList = new ArrayList<>();
final List<Control> modifyControlList = new ArrayList<>();
final List<Control> modifyDNControlList = new ArrayList<>();
getOperationControls(addControlList, deleteControlList, modifyControlList, modifyDNControlList);
addControls = StaticUtils.toArray(addControlList, Control.class);
deleteControls = StaticUtils.toArray(deleteControlList, Control.class);
modifyControls = StaticUtils.toArray(modifyControlList, Control.class);
modifyDNControls = StaticUtils.toArray(modifyDNControlList, Control.class);
} catch (final LDAPException e) {
Debug.debugException(e);
logCompletionMessage(true, e.getMessage());
return e.getResultCode();
}
// Get the connection pool to use to communicate with the directory
// server(s).
final LDAPConnectionPool connectionPool;
final int numThreads = numThreadsArg.getValue();
try {
connectionPool = getConnectionPool(numThreads, numThreads, 1, null, null, true, null);
connectionPool.setConnectionPoolName("parallel-update");
connectionPool.setRetryFailedOperationsDueToInvalidConnections((!neverRetryArg.isPresent()));
} catch (final LDAPException e) {
Debug.debugException(e);
logCompletionMessage(true, ERR_PARALLEL_UPDATE_CANNOT_CREATE_POOL.get(StaticUtils.getExceptionMessage(e)));
return e.getResultCode();
}
// Create the LDIF reader that will read the changes to process.
final LDIFReader ldifReader;
final String encryptionPassphrase;
try {
final ObjectPair<LDIFReader, String> ldifReaderPair = createLDIFReader();
ldifReader = ldifReaderPair.getFirst();
encryptionPassphrase = ldifReaderPair.getSecond();
} catch (final LDAPException e) {
Debug.debugException(e);
logCompletionMessage(true, e.getMessage());
connectionPool.close();
return e.getResultCode();
}
final AtomicReference<ResultCode> resultCodeRef = new AtomicReference<>(ResultCode.SUCCESS);
try {
// If the LDIF file is encrypted, then get the ID of the encryption
// settings definition (if any) used to generate the encryption key.
final String encryptionSettingsDefinitionID;
if (encryptionPassphrase == null) {
encryptionSettingsDefinitionID = null;
} else {
encryptionSettingsDefinitionID = getEncryptionSettingsDefinitionID();
}
// Create the LDIF writer that will be used to write rejects.
try {
rejectWriter = createRejectWriter(encryptionPassphrase, encryptionSettingsDefinitionID);
} catch (final LDAPException e) {
Debug.debugException(e);
logCompletionMessage(true, e.getMessage());
return ResultCode.LOCAL_ERROR;
}
// log of the changes that are attempted.
if (logFileArg.isPresent()) {
try {
logWriter = new PrintWriter(logFileArg.getValue());
} catch (final Exception e) {
Debug.debugException(e);
logCompletionMessage(true, ERR_PARALLEL_UPDATE_ERROR_CREATING_LOG_WRITER.get(logFileArg.getValue().getAbsolutePath(), StaticUtils.getExceptionMessage(e)));
return ResultCode.LOCAL_ERROR;
}
}
// Create The queue that will hold the operations to process.
final ParallelUpdateOperationQueue operationQueue = new ParallelUpdateOperationQueue(this, numThreads, (2 * numThreads));
// Create the rate limiter, if appropriate.
if (ratePerSecondArg.isPresent()) {
rateLimiter = new FixedRateBarrier(1000L, ratePerSecondArg.getValue());
} else {
rateLimiter = null;
}
// Create and start all of the threads that will be used to process
// requests.
final List<ParallelUpdateOperationThread> operationThreadList = new ArrayList<>(numThreads);
for (int i = 1; i <= numThreads; i++) {
final ParallelUpdateOperationThread operationThread = new ParallelUpdateOperationThread(this, connectionPool, operationQueue, i, rateLimiter, addControls, deleteControls, modifyControls, modifyDNControls, allowUndeleteArg.isPresent());
operationThreadList.add(operationThread);
operationThread.start();
}
// Create a progress monitor that will be used to report periodic status
// updates about the processing that has been performed.
final ParallelUpdateProgressMonitor progressMonitor = new ParallelUpdateProgressMonitor(this);
try {
processingStartTimeMillis = System.currentTimeMillis();
progressMonitor.start();
while (!shouldAbort.get()) {
final LDIFChangeRecord changeRecord;
try {
changeRecord = ldifReader.readChangeRecord(defaultAddArg.isPresent());
} catch (final LDIFException e) {
Debug.debugException(e);
if (e.mayContinueReading()) {
final String message = ERR_PARALLEL_UPDATE_RECOVERABLE_LDIF_EXCEPTION.get(ldifFileArg.getValue().getAbsolutePath(), e.getMessage());
logMessage(message);
reject(null, new LDAPException(ResultCode.DECODING_ERROR, message, e));
opsAttempted.incrementAndGet();
continue;
} else {
shouldAbort.set(true);
final String message = ERR_PARALLEL_UPDATE_UNRECOVERABLE_LDIF_EXCEPTION.get(ldifFileArg.getValue().getAbsolutePath(), StaticUtils.getExceptionMessage(e));
reject(null, new LDAPException(ResultCode.DECODING_ERROR, message, e));
logCompletionMessage(true, message);
return ResultCode.DECODING_ERROR;
}
} catch (final Exception e) {
Debug.debugException(e);
shouldAbort.set(true);
final String message = ERR_PARALLEL_UPDATE_ERROR_READING_LDIF_FILE.get(ldifFileArg.getValue().getAbsolutePath(), StaticUtils.getExceptionMessage(e));
reject(null, new LDAPException(ResultCode.LOCAL_ERROR, message, e));
logCompletionMessage(true, message);
return ResultCode.LOCAL_ERROR;
}
if (changeRecord == null) {
// We've reached the end of the LDIF file.
break;
} else {
try {
operationQueue.addChangeRecord(changeRecord);
} catch (final Exception e) {
Debug.debugException(e);
// This indicates that the attempt to enqueue the change record
// was interrupted. This shouldn't happen, but if it does, then
// mark it to be retried.
final LDAPException le = new LDAPException(ResultCode.LOCAL_ERROR, ERR_PARALLEL_UPDATE_ENQUEUE_FAILED.get(StaticUtils.getExceptionMessage(e)), e);
retry(changeRecord, le);
}
}
}
// If a failure was encountered, then abort.
if (shouldAbort.get()) {
resultCodeRef.compareAndSet(ResultCode.SUCCESS, ResultCode.LOCAL_ERROR);
return resultCodeRef.get();
}
// Indicate that we've reached the end of the LDIF file.
out();
wrapOut(0, WRAP_COLUMN, INFO_PARALLEL_UPDATE_END_OF_LDIF.get());
out();
// Wait for the operation queue to become idle so that we know there
// are no more outstanding operations to be processed.
operationQueue.waitUntilIdle();
initialAttempted = opsAttempted.get();
initialSucceeded = opsSucceeded.get();
// If there are any operations to retry, then do so now.
Map<DN, List<ObjectPair<LDIFChangeRecord, LDAPException>>> retryQueueCopy;
synchronized (retryQueue) {
retryQueueCopy = new TreeMap<>(retryQueue);
retryQueue.clear();
}
int lastRetryQueueSize = 0;
while ((!retryQueueCopy.isEmpty()) && (retryQueueCopy.size() != lastRetryQueueSize)) {
out();
wrapOut(0, WRAP_COLUMN, INFO_PARALLEL_UPDATE_BEGINNING_RETRY.get(retryQueueCopy.size()));
out();
for (final Map.Entry<DN, List<ObjectPair<LDIFChangeRecord, LDAPException>>> e : retryQueueCopy.entrySet()) {
for (final ObjectPair<LDIFChangeRecord, LDAPException> p : e.getValue()) {
if (shouldAbort.get()) {
resultCodeRef.compareAndSet(ResultCode.SUCCESS, ResultCode.LOCAL_ERROR);
return resultCodeRef.get();
}
final LDIFChangeRecord changeRecord = p.getFirst();
try {
operationQueue.addChangeRecord(changeRecord);
retryQueueSize.decrementAndGet();
} catch (final Exception ex) {
Debug.debugException(ex);
// This indicates that the attempt to enqueue the change record
// was interrupted. This shouldn't happen, but if it does, then
// mark it to be retried.
final LDAPException le = new LDAPException(ResultCode.LOCAL_ERROR, ERR_PARALLEL_UPDATE_ENQUEUE_FAILED.get(StaticUtils.getExceptionMessage(ex)), ex);
retry(changeRecord, le);
}
}
}
operationQueue.waitUntilIdle();
lastRetryQueueSize = retryQueueCopy.size();
synchronized (retryQueue) {
retryQueueCopy = new TreeMap<>(retryQueue);
retryQueue.clear();
}
}
// then reject any of the remaining operations.
synchronized (retryQueue) {
final int remainingToRetry = retryQueueCopy.size();
if (remainingToRetry > 0) {
if (remainingToRetry == 1) {
wrapErr(0, WRAP_COLUMN, ERR_PARALLEL_UPDATE_NO_PROGRESS_ONE.get());
} else {
wrapErr(0, WRAP_COLUMN, ERR_PARALLEL_UPDATE_NO_PROGRESS_MULTIPLE.get(remainingToRetry));
}
}
for (final Map.Entry<DN, List<ObjectPair<LDIFChangeRecord, LDAPException>>> e : retryQueueCopy.entrySet()) {
for (final ObjectPair<LDIFChangeRecord, LDAPException> p : e.getValue()) {
reject(p.getFirst(), p.getSecond());
retryQueueSize.decrementAndGet();
}
}
}
} finally {
operationQueue.setEndOfLDIF();
operationQueue.waitUntilIdle();
for (final ParallelUpdateOperationThread operationThread : operationThreadList) {
try {
operationThread.join();
} catch (final Exception e) {
Debug.debugException(e);
logCompletionMessage(true, ERR_PARALLEL_UPDATE_CANNOT_JOIN_THREAD.get(operationThread.getName(), StaticUtils.getExceptionMessage(e)));
resultCodeRef.compareAndSet(ResultCode.SUCCESS, ResultCode.LOCAL_ERROR);
}
}
try {
progressMonitor.stopRunning();
progressMonitor.join();
} catch (final Exception e) {
Debug.debugException(e);
logCompletionMessage(true, ERR_PARALLEL_UPDATE_CANNOT_JOIN_PROGRESS_MONITOR.get(StaticUtils.getExceptionMessage(e)));
resultCodeRef.compareAndSet(ResultCode.SUCCESS, ResultCode.LOCAL_ERROR);
}
}
} finally {
connectionPool.close();
if (rejectWriter != null) {
try {
rejectWriter.close();
} catch (final Exception e) {
Debug.debugException(e);
logCompletionMessage(true, ERR_PARALLEL_UPDATE_ERROR_CLOSING_REJECT_WRITER.get(rejectFileArg.getValue().getAbsolutePath(), StaticUtils.getExceptionMessage(e)));
resultCodeRef.compareAndSet(ResultCode.SUCCESS, ResultCode.LOCAL_ERROR);
}
}
if (logWriter != null) {
try {
logWriter.close();
} catch (final Exception e) {
Debug.debugException(e);
logCompletionMessage(true, ERR_PARALLEL_UPDATE_ERROR_CLOSING_LOG_WRITER.get(logFileArg.getValue().getAbsolutePath(), StaticUtils.getExceptionMessage(e)));
resultCodeRef.compareAndSet(ResultCode.SUCCESS, ResultCode.LOCAL_ERROR);
}
}
try {
ldifReader.close();
} catch (final Exception e) {
Debug.debugException(e);
logCompletionMessage(true, WARN_PARALLEL_UPDATE_ERROR_CLOSING_READER.get(ldifFileArg.getValue().getAbsolutePath(), StaticUtils.getExceptionMessage(e)));
resultCodeRef.compareAndSet(ResultCode.SUCCESS, ResultCode.LOCAL_ERROR);
}
}
// If we've gotten here, then processing has completed. Print some summary
// messages and return an appropriate result code.
final long processingDurationMillis = System.currentTimeMillis() - processingStartTimeMillis;
final long numAttempts = opsAttempted.get();
final long numSuccesses = opsSucceeded.get();
final long numRejects = opsRejected.get();
final long retryAttempts = numAttempts - initialAttempted;
final long retrySuccesses = numSuccesses - initialSucceeded;
out(INFO_PARALLEL_UPDATE_DONE.get(getToolName()));
out(INFO_PARALLEL_UPDATE_SUMMARY_OPS_ATTEMPTED.get(numAttempts));
if (retryAttempts > 0L) {
out(INFO_PARALLEL_UPDATE_SUMMARY_INITIAL_ATTEMPTS.get(initialAttempted));
out(INFO_PARALLEL_UPDATE_SUMMARY_RETRY_ATTEMPTS.get(retryAttempts));
}
out(INFO_PARALLEL_UPDATE_SUMMARY_OPS_SUCCEEDED.get(numSuccesses));
if (retryAttempts > 0) {
out(INFO_PARALLEL_UPDATED_OPS_SUCCEEDED_INITIAL.get(initialSucceeded));
out(INFO_PARALLEL_UPDATED_OPS_SUCCEEDED_RETRY.get(retrySuccesses));
}
out(INFO_PARALLEL_UPDATE_SUMMARY_OPS_REJECTED.get(numRejects));
out(INFO_PARALLEL_UPDATE_SUMMARY_DURATION.get(StaticUtils.millisToHumanReadableDuration(processingDurationMillis)));
if ((numAttempts > 0L) && (processingDurationMillis > 0L)) {
final double attemptsPerSecond = numAttempts * 1_000.0d / processingDurationMillis;
final DecimalFormat decimalFormat = new DecimalFormat("0.000");
out(INFO_PARALLEL_UPDATE_SUMMARY_RATE.get(decimalFormat.format(attemptsPerSecond)));
}
if (numRejects == 0L) {
completionMessage.compareAndSet(null, INFO_PARALLEL_UPDATE_COMPLETION_MESSAGE_ALL_SUCCEEDED.get(getToolName()));
} else if (numRejects == 1L) {
completionMessage.compareAndSet(null, INFO_PARALLEL_UPDATE_COMPLETION_MESSAGE_ONE_REJECTED.get(getToolName()));
} else {
completionMessage.compareAndSet(null, INFO_PARALLEL_UPDATE_COMPLETION_MESSAGE_MULTIPLE_REJECTED.get(getToolName(), numRejects));
}
ResultCode finalResultCode = resultCodeRef.get();
if ((finalResultCode == ResultCode.SUCCESS) && useFirstRejectResultCodeAsExitCodeArg.isPresent() && (firstRejectResultCode.get() != null)) {
finalResultCode = firstRejectResultCode.get();
}
return finalResultCode;
}
Aggregations