
java.fedora.server.journal.readerwriter.multifile.LockingFollowingJournalReader Maven / Gradle / Ivy
Show all versions of fcrepo-client Show documentation
/*
* -----------------------------------------------------------------------------
*
* License and Copyright: The contents of this file are subject to 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.fedora-commons.org/licenses.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
*
* The entire file consists of original code.
* Copyright © 2008 Fedora Commons, Inc.
*
Copyright © 2002-2007 The Rector and Visitors of the University of
* Virginia and Cornell University
* All rights reserved.
*
* -----------------------------------------------------------------------------
*/
package fedora.server.journal.readerwriter.multifile;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import fedora.server.journal.JournalException;
import fedora.server.journal.ServerInterface;
import fedora.server.journal.helpers.ParameterHelper;
import fedora.server.journal.recoverylog.JournalRecoveryLog;
/**
*
* Title: LockingFollowingJournalReader.java
*
*
* Description: A Following Journal Reader that can be made quiescent by
* the presense of a lock file. This works like the
* MultiFileFollowingJournalReader, except that when looking for the next
* Journal file to be processed, it will take a moment to check the locking
* protocol. If a lock has been requested, it will accept the lock, and ignore
* any additional Journal files if present.
*
*
* Polling continues, however. At each polling interval, the reader will check
* for the lock request. If the request has been removed, the lock acceptance
* will be removed also, and the reader will process the next Journal file, if
* one is found.
*
*
* @author [email protected]
* @version $Id: LockingFollowingJournalReader.java 5025 2006-09-01 22:08:17
* +0000 (Fri, 01 Sep 2006) cwilper $
*/
public class LockingFollowingJournalReader
extends MultiFileJournalReader {
/** How many milliseconds between polls? */
private final long pollingIntervalMillis;
/**
* The name of the file that signals a request to go quiescent after the
* current journal file.
*/
private final File lockRequestedFile;
/**
* The name of the file that acknowledges a request to go quiescent after
* the current journal file.
*/
private final File lockAcceptedFile;
/** Poll immediately for the next file, or pause first? */
private final boolean pauseBeforePolling;
/** Currently quiescent? */
private boolean wasLocked = false;
/**
* Require parameters for polling interval, lock request filename and lock
* acceptance filename.
*/
public LockingFollowingJournalReader(Map parameters,
String role,
JournalRecoveryLog recoveryLog,
ServerInterface server)
throws JournalException {
super(parameters, role, recoveryLog, server);
pollingIntervalMillis =
MultiFileJournalHelper
.parseParametersForPollingInterval(parameters);
lockRequestedFile =
new File(MultiFileJournalHelper
.getRequiredParameter(parameters,
PARAMETER_LOCK_REQUESTED_FILENAME));
lockAcceptedFile =
new File(MultiFileJournalHelper
.getRequiredParameter(parameters,
PARAMETER_LOCK_ACCEPTED_FILENAME));
pauseBeforePolling =
ParameterHelper
.getOptionalBooleanParameter(parameters,
PARAMETER_PAUSE_BEFORE_POLLING,
false);
}
/**
* Process the locking mechanism. If we are not locked, we should look for
* another journal file to process. Ask for a new file, using the superclass
* method, but if none is found, wait for a while and repeat. This will
* continue until we get a server shutdown signal.
*/
@Override
protected synchronized JournalInputFile openNextFile()
throws JournalException {
while (open) {
boolean locked = processLockingMechanism();
if (pauseBeforePolling) {
try {
wait(pollingIntervalMillis);
} catch (InterruptedException e) {
// no special action on interrupt.
}
}
if (!locked) {
JournalInputFile nextFile = super.openNextFile();
if (nextFile != null) {
return nextFile;
}
}
try {
wait(pollingIntervalMillis);
} catch (InterruptedException e) {
// no special action on interrupt.
}
}
return null;
}
/**
* If the server requests a shutdown, stop waiting the next file to come in.
*/
@Override
public synchronized void shutdown() throws JournalException {
super.shutdown();
notifyAll();
}
/**
* If we see a lock request, issue an acceptance. If we do not, withdraw the
* acceptance.
*
* @return true if locked, false if not locked.
* @throws JournalException
* if we fail to create the 'lock accepted' file.
*/
private boolean processLockingMechanism() throws JournalException {
boolean locked;
if (lockRequestedFile.exists()) {
try {
if (!lockAcceptedFile.exists()) {
lockAcceptedFile.createNewFile();
}
} catch (IOException e) {
throw new JournalException("Unable to create 'Lock Accepted' file at '"
+ lockAcceptedFile.getPath() + "'");
}
locked = true;
} else {
if (lockAcceptedFile.exists()) {
lockAcceptedFile.delete();
}
locked = false;
}
if (locked && !wasLocked) {
recoveryLog.log("Lock request detected: "
+ lockRequestedFile.getPath() + ", Lock accepted: "
+ lockAcceptedFile.getPath());
} else if (wasLocked && !locked) {
recoveryLog.log("Lock request removed: "
+ lockRequestedFile.getPath());
}
wasLocked = locked;
return locked;
}
}