Skip to content
Snippets Groups Projects
Commit 253d461d authored by brinn's avatar brinn
Browse files

[DMV-31] add support for detection and signaling of errors

SVN: 7201
parent dd9ea975
No related branches found
No related tags found
No related merge requests found
Showing with 125 additions and 27 deletions
......@@ -86,9 +86,10 @@ public final class HighwaterMarkDirectoryScanningHandler extends
//
@Override
public final boolean mayHandle(final IScannedStore scannedStore, final StoreItem storeItem)
public HandleInstruction mayHandle(final IScannedStore scannedStore, final StoreItem storeItem)
{
return mayHandle() == false ? false : super.mayHandle(scannedStore, storeItem);
return mayHandle() == false ? HandleInstruction.ERROR : super.mayHandle(
scannedStore, storeItem);
}
}
......@@ -44,13 +44,13 @@ public class DirectoryScanningHandlerInterceptor implements IDirectoryScanningHa
directoryScanningHandler.beforeHandle();
}
public boolean mayHandle(final IScannedStore scannedStore, final StoreItem storeItem)
public HandleInstruction mayHandle(final IScannedStore scannedStore, final StoreItem storeItem)
{
return directoryScanningHandler.mayHandle(scannedStore, storeItem);
}
public void finishItemHandle(final IScannedStore scannedStore, final StoreItem storeItem)
public boolean finishItemHandle(final IScannedStore scannedStore, final StoreItem storeItem)
{
directoryScanningHandler.finishItemHandle(scannedStore, storeItem);
return directoryScanningHandler.finishItemHandle(scannedStore, storeItem);
}
}
......@@ -29,6 +29,7 @@ import ch.systemsx.cisd.common.logging.ConditionalNotificationLogger;
import ch.systemsx.cisd.common.logging.ISimpleLogger;
import ch.systemsx.cisd.common.logging.LogCategory;
import ch.systemsx.cisd.common.logging.LogFactory;
import ch.systemsx.cisd.common.utilities.IDirectoryScanningHandler.HandleInstruction;
/**
* A {@link TimerTask} that scans a source directory for entries that are accepted by some
......@@ -42,7 +43,7 @@ import ch.systemsx.cisd.common.logging.LogFactory;
*
* @author Bernd Rinn
*/
public final class DirectoryScanningTimerTask extends TimerTask
public final class DirectoryScanningTimerTask extends TimerTask implements ITimerTaskStatusProvider
{
private static final Logger operationLog =
......@@ -59,6 +60,10 @@ public final class DirectoryScanningTimerTask extends TimerTask
private final ConditionalNotificationLogger notificationLogger;
private int numberOfProcessedItems;
private int numberOfErrorItems;
/**
* Indicates that we should try to exit the {@link #run()} method as soon as possible.
* <p>
......@@ -200,12 +205,14 @@ public final class DirectoryScanningTimerTask extends TimerTask
}
try
{
int numberOfItemsHandled;
numberOfProcessedItems = 0;
numberOfErrorItems = 0;
int numberOfItemsProcessedInLastRound;
do
{
numberOfItemsProcessedInLastRound = 0;
final StoreItem[] storeItems = listStoreItems();
final int numberOfItems = storeItems.length;
numberOfItemsHandled = numberOfItems;
directoryScanningHandler.beforeHandle();
for (int i = 0; i < numberOfItems; i++)
{
......@@ -214,14 +221,17 @@ public final class DirectoryScanningTimerTask extends TimerTask
{
if (operationLog.isDebugEnabled())
{
operationLog.debug(String.format("Scan of store '%s' has been cancelled. "
+ "Following items have NOT been handled: %s.", sourceDirectory,
CollectionUtils.abbreviate(ArrayUtils.subarray(storeItems, i + 1,
numberOfItems), 10)));
operationLog.debug(String.format(
"Scan of store '%s' has been cancelled. "
+ "Following items have NOT been handled: %s.",
sourceDirectory, CollectionUtils.abbreviate(ArrayUtils
.subarray(storeItems, i + 1, numberOfItems), 10)));
}
return;
}
if (directoryScanningHandler.mayHandle(sourceDirectory, storeItem))
final HandleInstruction instruction =
directoryScanningHandler.mayHandle(sourceDirectory, storeItem);
if (HandleInstruction.PROCESS.equals(instruction))
{
try
{
......@@ -231,26 +241,39 @@ public final class DirectoryScanningTimerTask extends TimerTask
operationLog.trace(String.format(
"Following store item '%s' has been handled.", storeItem));
}
++numberOfProcessedItems;
++numberOfItemsProcessedInLastRound;
} catch (final Exception ex)
{
// Do not stop when processing of one file has failed,
// continue with other files.
++numberOfErrorItems;
printNotification(ex);
} finally
{
directoryScanningHandler.finishItemHandle(sourceDirectory, storeItem);
final boolean ok =
directoryScanningHandler.finishItemHandle(sourceDirectory,
storeItem);
if (ok == false)
{
++numberOfErrorItems;
}
}
} else
{
--numberOfItemsHandled;
if (HandleInstruction.ERROR.equals(instruction))
{
++numberOfErrorItems;
}
if (operationLog.isTraceEnabled())
{
operationLog.trace(String.format(
"Following store item '%s' has NOT been handled.", storeItem));
"Following store item '%s' has NOT been handled (%s).",
storeItem, instruction));
}
}
}
} while (numberOfItemsHandled > 0);
} while (numberOfItemsProcessedInLastRound > 0);
} catch (final Exception ex)
{
printNotification(ex);
......@@ -261,6 +284,20 @@ public final class DirectoryScanningTimerTask extends TimerTask
}
}
//
// ITimerTaskStatusProvider
//
public boolean hasErrors()
{
return (numberOfErrorItems > 0);
}
public boolean hasPerformedMeaningfulWork()
{
return (numberOfProcessedItems > 0);
}
//
// Helper classes
//
......@@ -283,4 +320,5 @@ public final class DirectoryScanningTimerTask extends TimerTask
*/
String getLocationDescription(StoreItem item);
}
}
......@@ -129,19 +129,31 @@ public final class FaultyPathDirectoryScanningHandler implements IDirectoryScann
checkForFaultyPathsFileChanged();
}
public final boolean mayHandle(final IScannedStore scannedStore, final StoreItem storeItem)
public final HandleInstruction mayHandle(final IScannedStore scannedStore, final StoreItem storeItem)
{
return isFaultyPath(scannedStore, storeItem) == false
&& isFaultyPathsFile(scannedStore, storeItem) == false;
if (isFaultyPathsFile(scannedStore, storeItem))
{
return HandleInstruction.IGNORE;
} else if (isFaultyPath(scannedStore, storeItem))
{
return HandleInstruction.ERROR;
} else
{
return HandleInstruction.PROCESS;
}
}
public final void finishItemHandle(final IScannedStore scannedStore, final StoreItem storeItem)
public final boolean finishItemHandle(final IScannedStore scannedStore, final StoreItem storeItem)
{
// If the item still exists, we assume that it has not been handled. So it
// should be added to the faulty paths.
if (scannedStore.existsOrError(storeItem))
{
addToFaultyPaths(scannedStore, storeItem);
return false;
} else
{
return true;
}
}
......
......@@ -28,6 +28,14 @@ import ch.systemsx.cisd.common.utilities.DirectoryScanningTimerTask.IScannedStor
public interface IDirectoryScanningHandler
{
/**
* The instruction of whether to process an item or not.
*/
public enum HandleInstruction
{
PROCESS, IGNORE, ERROR
}
/**
* Is performed just before handling all the items contained in the store.
*/
......@@ -35,12 +43,15 @@ public interface IDirectoryScanningHandler
/**
* Whether given <code>storeItem</code> found in given <var>scannedStore</var> should be
* processed or not.
* processed or not, and whether not processing it constitues an error or not.
*/
public boolean mayHandle(IScannedStore scannedStore, StoreItem storeItem);
public HandleInstruction mayHandle(IScannedStore scannedStore, StoreItem storeItem);
/**
* Finishes and closes the handling of given <var>storeItem</var>.
*
* @returns <code>true</code>, if the item has been handled correctly and <code>false</code>
* if an error occurred.
*/
public void finishItemHandle(IScannedStore scannedStore, StoreItem storeItem);
public boolean finishItemHandle(IScannedStore scannedStore, StoreItem storeItem);
}
/*
* Copyright 2008 ETH Zuerich, CISD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.systemsx.cisd.common.utilities;
/**
* A provider for status information about the last run of a {@link java.util.TimerTask}.
*
* @author Bernd Rinn
*/
public interface ITimerTaskStatusProvider
{
public boolean hasPerformedMeaningfulWork();
public boolean hasErrors();
}
......@@ -25,6 +25,8 @@ import java.util.TimerTask;
import org.testng.annotations.Test;
import ch.systemsx.cisd.common.utilities.ITimerTaskStatusProvider;
/**
*
*
......@@ -77,7 +79,7 @@ public class TimerTaskWithListenersTest
recorder.add(name + ".canceling");
}
public void finishRunning()
public void finishRunning(ITimerTaskStatusProvider statusProviderOrNull)
{
recorder.add(name + ".finishRunning");
}
......
......@@ -33,6 +33,7 @@ import ch.systemsx.cisd.common.highwatermark.HighwaterMarkWatcher.IFreeSpaceProv
import ch.systemsx.cisd.common.utilities.IDirectoryScanningHandler;
import ch.systemsx.cisd.common.utilities.StoreItem;
import ch.systemsx.cisd.common.utilities.DirectoryScanningTimerTask.IScannedStore;
import ch.systemsx.cisd.common.utilities.IDirectoryScanningHandler.HandleInstruction;
/**
* Test cases for the {@link HighwaterMarkDirectoryScanningHandler}.
......@@ -134,7 +135,8 @@ public final class HighwaterMarkDirectoryScanningHandlerTest
}
}
});
boolean mayHandle = scanningHandler.mayHandle(scannedStore, storeItem);
boolean mayHandle =
HandleInstruction.PROCESS.equals(scanningHandler.mayHandle(scannedStore, storeItem));
assertEquals(freeSpace > HIGHWATER_MARK, mayHandle);
context.assertIsSatisfied();
}
......@@ -163,7 +165,8 @@ public final class HighwaterMarkDirectoryScanningHandlerTest
}
}
});
boolean mayHandle = scanningHandler.mayHandle(scannedStore, storeItem);
boolean mayHandle =
HandleInstruction.PROCESS.equals(scanningHandler.mayHandle(scannedStore, storeItem));
assertEquals(freeSpace > HIGHWATER_MARK, mayHandle);
context.assertIsSatisfied();
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment