Class XALogger
- java.lang.Object
-
- org.objectweb.howl.log.LogObject
-
- org.objectweb.howl.log.Logger
-
- org.objectweb.howl.log.xa.XALogger
-
- All Implemented Interfaces:
LogEventListener
public class XALogger extends Logger implements LogEventListener
A specialized subclass ofLogger
intended to provide functionality required by any XA Transaction Manager.This class provides wrappers for all public methods of Logger to allow enforcement of policies that are in place for an XA TM log.
This class implements
LogEventListener
. During logOverflowNotification processing, entries in the activeTx[] are re-logged and the active mark is moved.If the application has called setLogEventListener, then Log events are forwarded to the application after they are processed by this class.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private class
XALogger.OpenReplayListener
private class used by XALogger to replay the log during log open processing.private static class
XALogger.XAReplayListener
private class used by XALogger.replay() methods.
-
Field Summary
Fields Modifier and Type Field Description (package private) XACommittingTx[]
activeTx
array of transactions in COMMIT phase and waiting for DONE.(package private) java.lang.Object
activeTxLock
lock used to synchronize access to the availableTx array, atxGet and atxPut members.(package private) int
atxGet
workerID into availableTx[] used to remove an entry.(package private) int
atxPut
workerID into availableTx[] used to return (add) an entry.(package private) int
atxUsed
number of used entries in activeTx table.(package private) XACommittingTx[]
availableTx
array of available XACommittingTx objects.(package private) LogEventListener
eventListener
LogEventListener registered by TM that instantiated this XALogger.(package private) int
growActiveTxArrayCount
number of times the activeTx table was resized to accomodate a larger number of transactions in the COMMITTING state.(package private) int
maxAtxUsed
maximum number of used entries.(package private) int
movedRecordCount
number of records moved by log overflow notification processor.(package private) long
overflowFence
log key below which COMMIT records will be copied forward by logOverflowNotification to avoid log overflow exceptions.(package private) int
overflowNotificationCount
number of times log overflow notification event was called.(package private) boolean
replayNeeded
Set true in open() to indicate that replay is required prior to allowing any calls to put() methods.(package private) long
totalWaitForThis
number of ms that threads waited for overflow processing to complete.(package private) int
waitForThisCount
number of times threads waited for overflow processing to complete.
-
Constructor Summary
Constructors Constructor Description XALogger()
Construct a Logger using default Configuration object.XALogger(Configuration config)
Construct a Logger using a Configuration supplied by the caller.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description private XACommittingTx
activeTxAdd(long key, byte[][] record)
Used by putCommit() and by OpenReplayListener#onRecord() to add entries to the activeTx table.void
activeTxDisplay()
displays entries in the activeTx table.private void
checkPutEnabled()
void
close()
close the Log files and perform necessary cleanup tasks.int
getActiveTxUsed()
Used by TM and test cases to obtain the number of entries in the activeTx table.java.lang.String
getStats()
return an XML node containing statistics for this object along with the base Logger, the LogFile pool and the LogBuffer pool.private long
getTotalWaitForThis()
Provide synchronized access to totalWaitForThis.private int
getWaitForThisCount()
Provide synchronized access to waitForThisCount.private void
growActiveTxArray()
Resize the activeTx and availableTx tables to accomodate larger number of transactions in the COMMITTING state.private void
init()
Common initialization for all constructors.boolean
isLoggable(int level)
implements LogEventListener#isLoggable().void
log(int level, java.lang.String message)
delegates log request to the callers event listener.void
log(int level, java.lang.String message, java.lang.Throwable thrown)
delegates log request to the callers event listener.void
logOverflowNotification(long overflowFence)
called by Logger when log file is about to overflow.private void
onpWait()
wait for overflow notification processor to finish.void
open()
Not supported for XALogger.void
open(ReplayListener listener)
calls super.open() to perform standard open functionality then replays the log to rebuild the activeTx table.long
put(byte[][] data, boolean sync)
add a USER record consisting of byte[][] to the log.long
put(byte[] data, boolean sync)
add a USER record consisting of byte[] to the log.XACommittingTx
putCommit(byte[][] record)
Write a begin COMMIT record to the log.long
putDone(byte[][] record, XACommittingTx tx)
Write a DONE record to the log.void
replay(ReplayListener listener)
Wrapp Logger#replay(ReplayListener) so we can intercept onRecord() notifications to process XACOMMIT and XACOMMITMOVED records.void
replay(ReplayListener listener, long key)
Wrapp Logger#replay(ReplayListener, long) so we can intercept onRecord() notifications to process XACOMMIT and XACOMMITMOVED records.void
replayActiveTx(ReplayListener listener)
Called by the TM to receive copies of the active transaction entries.void
setLogEventListener(LogEventListener eventListener)
Saves a reference to callers LogEventListener.-
Methods inherited from class org.objectweb.howl.log.Logger
get, getActiveMark, getNext, mark, mark, put, replay, setAutoMark
-
-
-
-
Field Detail
-
activeTx
XACommittingTx[] activeTx
array of transactions in COMMIT phase and waiting for DONE.Array is grown as needed to accomodate larger number of transactions in COMMITING state.
When the Logger detects that a log file overflow condition is about to occur
LogEventListener.logOverflowNotification(long)
is invoked to allow the application to move older records forward in the log. This approach avoides the need to move records forward every time a log file switch occurs.During the logOverflowNotification, activeTx[] is scanned for entries with log keys older than the key specified on the notification. Since this processing only needs to occur when a log file is about to overflow, the array is used as an alternative to a linked list to eliminate the overhead of managing the linked list for every log record.
-
availableTx
XACommittingTx[] availableTx
array of available XACommittingTx objects.Each entry in the array is associated with an entry in activeTx[].
- Entries are obtained using the atxGet member.
- Entries are returned to the list using the atxPut member.
- The activeTx and availableTx arrays are grown as needed.
-
atxGet
int atxGet
workerID into availableTx[] used to remove an entry.
-
atxPut
int atxPut
workerID into availableTx[] used to return (add) an entry.
-
atxUsed
int atxUsed
number of used entries in activeTx table.table is grown when atxUsed is equal to the size of the table and we are trying to add one more entry.
-
maxAtxUsed
int maxAtxUsed
maximum number of used entries.
-
activeTxLock
final java.lang.Object activeTxLock
lock used to synchronize access to the availableTx array, atxGet and atxPut members.
-
growActiveTxArrayCount
int growActiveTxArrayCount
number of times the activeTx table was resized to accomodate a larger number of transactions in the COMMITTING state.
-
overflowNotificationCount
int overflowNotificationCount
number of times log overflow notification event was called.
-
movedRecordCount
int movedRecordCount
number of records moved by log overflow notification processor.
-
totalWaitForThis
long totalWaitForThis
number of ms that threads waited for overflow processing to complete.
-
waitForThisCount
int waitForThisCount
number of times threads waited for overflow processing to complete.
-
overflowFence
long overflowFence
log key below which COMMIT records will be copied forward by logOverflowNotification to avoid log overflow exceptions.synchronized on this
-
eventListener
LogEventListener eventListener
LogEventListener registered by TM that instantiated this XALogger.XALogger may pass some notifications on to the TM via this.eventListener.
-
replayNeeded
boolean replayNeeded
Set true in open() to indicate that replay is required prior to allowing any calls to put() methods.Calls to any put() method while replayNeeded is true will cause an exception to be thrown.
-
-
Constructor Detail
-
XALogger
public XALogger() throws java.io.IOException
Construct a Logger using default Configuration object.- Throws:
java.io.IOException
-
XALogger
public XALogger(Configuration config) throws java.io.IOException
Construct a Logger using a Configuration supplied by the caller.- Parameters:
config
- Configuration object- Throws:
java.io.IOException
-
-
Method Detail
-
growActiveTxArray
private void growActiveTxArray()
Resize the activeTx and availableTx tables to accomodate larger number of transactions in the COMMITTING state.PRECONDITION: thread has activeTxLock shut
-
init
private void init()
Common initialization for all constructors.
-
checkPutEnabled
private void checkPutEnabled() throws LogClosedException
- Throws:
LogClosedException
-
put
public long put(byte[] data, boolean sync) throws LogClosedException, LogRecordSizeException, LogFileOverflowException, java.lang.InterruptedException, java.io.IOException
add a USER record consisting of byte[] to the log.waits for overflow notification processing to complete prior to putting the data to the log.
- Overrides:
put
in classLogger
- Parameters:
data
- byte[] to be written to logsync
- true if caller wishes to block waiting for the record to force to disk.- Returns:
- log key for the record
- Throws:
LogClosedException
- If the TM has called open() but has not called replay(). Also thrown if log is actually closed. Check the toString() for details.LogRecordSizeException
LogFileOverflowException
java.lang.InterruptedException
java.io.IOException
- See Also:
Logger.put(byte[], boolean)
-
put
public long put(byte[][] data, boolean sync) throws LogClosedException, LogRecordSizeException, LogFileOverflowException, java.lang.InterruptedException, java.io.IOException
add a USER record consisting of byte[][] to the log.waits for overflow notification processing to complete prior to putting the data to the log.
- Overrides:
put
in classLogger
- Parameters:
data
- record datasync
- true if call should block until force- Returns:
- a key that can be used to locate the record. Some implementations may use the key as a correlation ID to associate related records. When automark is disabled (false) the caller must invoke mark() using this key to indicate the location of the oldest active entry in the log.
- Throws:
LogClosedException
- If the TM has called open() but has not called replay(). Also thrown if log is actually closed. Check the toString() for details.LogRecordSizeException
LogFileOverflowException
java.lang.InterruptedException
java.io.IOException
- See Also:
Logger.put(byte[][], boolean)
-
onpWait
private void onpWait() throws java.lang.InterruptedException
wait for overflow notification processor to finish.failure to do might cause the overflow processor itself to get LogFileOverflowException.
- Throws:
java.lang.InterruptedException
-
putCommit
public XACommittingTx putCommit(byte[][] record) throws LogClosedException, LogRecordSizeException, LogFileOverflowException, java.lang.InterruptedException, java.io.IOException
Write a begin COMMIT record to the log.Call blocks until the data is forced to disk.
- Parameters:
record
- byte[][] containing data to be logged- Returns:
- XACommittingTx object to be used whe putting the DONE record.
- Throws:
LogClosedException
- If the TM has called open() but has not called replay(). Also thrown if log is actually closed. Check the toString() for details.java.io.IOException
java.lang.InterruptedException
LogFileOverflowException
LogRecordSizeException
-
activeTxAdd
private XACommittingTx activeTxAdd(long key, byte[][] record)
Used by putCommit() and by OpenReplayListener#onRecord() to add entries to the activeTx table.- Parameters:
key
- log key for the XACOMMIT recordrecord
- byte[][] of record data- Returns:
- XACommitting object representing the XACOMMIT data record in the log.
-
putDone
public long putDone(byte[][] record, XACommittingTx tx) throws LogClosedException, LogRecordSizeException, LogFileOverflowException, java.lang.InterruptedException, java.io.IOException
Write a DONE record to the log.Remove XACommittingTx object from the list of active transactions.
- Parameters:
record
- byte[][] containing data to be logged.If
record
isnull
then no user data is written to the journal.tx
- the XACommittingTx that was returned by the putCommit() routine for this transaction.- Returns:
- long log key for the
record
byte[][].If
record is null, then return is 0L.
- Throws:
java.io.IOException
java.lang.InterruptedException
LogFileOverflowException
LogRecordSizeException
LogClosedException
- If the TM has called open() but has not called replay(). Also thrown if log is actually closed. Check the toString() for details.
-
isLoggable
public boolean isLoggable(int level)
implements LogEventListener#isLoggable().- Specified by:
isLoggable
in interfaceLogEventListener
- Parameters:
level
- a logging level defined by LogEventListener- Returns:
- true if the log level is being logged
- See Also:
java.util.logging.Logger#isLoggable()
-
log
public void log(int level, java.lang.String message)
delegates log request to the callers event listener.- Specified by:
log
in interfaceLogEventListener
- Parameters:
level
- log levelmessage
- text to be logged
-
log
public void log(int level, java.lang.String message, java.lang.Throwable thrown)
delegates log request to the callers event listener.- Specified by:
log
in interfaceLogEventListener
- Parameters:
level
- log levelmessage
- text to be loggedthrown
- Throwable related to event being logged
-
logOverflowNotification
public void logOverflowNotification(long overflowFence)
called by Logger when log file is about to overflow.copies XACommittingTx records forward to allow reuse of older log file space.
calls Logger.mark() to set the new active mark at the completion of the scan.
Exceptions are ignored. Hopefully they will be reported to the TM when a transaction thread attempts to write a log record.
While we are processing activeTx[] we publish the overflowFence so putCommit knows that any record it stores with a key below the fence must be re-put.
This notification is not forwarded to the LogEventListener eventListener that was registered by the TM.
- Specified by:
logOverflowNotification
in interfaceLogEventListener
- Parameters:
overflowFence
- COMMIT records with log keys lower than fence must be moved. All others can be ignored for now.
-
getStats
public java.lang.String getStats()
return an XML node containing statistics for this object along with the base Logger, the LogFile pool and the LogBuffer pool.
-
getWaitForThisCount
private final int getWaitForThisCount()
Provide synchronized access to waitForThisCount.- Returns:
- waitForThisCount
-
getTotalWaitForThis
private final long getTotalWaitForThis()
Provide synchronized access to totalWaitForThis.- Returns:
- totalWaitForThis
-
setLogEventListener
public void setLogEventListener(LogEventListener eventListener)
Saves a reference to callers LogEventListener.Some LogEventListener notifications may be passed onto the callers eventListener. Refer to javadocs in this source for individual notifications to determine if the notification is passed on to the TM.
- Overrides:
setLogEventListener
in classLogger
- Parameters:
eventListener
- object to be notified of logger events.
-
open
public void open()
Not supported for XALogger.XALogger must rebuild the activeTx table prior to allowing any calls to put() methods. To enforce this, callers must use the
open(ReplayListener)
method.
-
open
public void open(ReplayListener listener) throws InvalidFileSetException, LogConfigurationException, InvalidLogBufferException, LogClosedException, java.lang.ClassNotFoundException, java.io.IOException, java.lang.InterruptedException
calls super.open() to perform standard open functionality then replays the log to rebuild the activeTx table.Sets replayNeeded flag to block calls to put() methods until the replay is complete. (This may be unnecessary because the replay blocks until it is complete, but we do this to prevent the TM from trying to make log entries on another thread before the log is fully open.)
During the replay, the XALogger calls the TM's listener.onRecord() with an XALogRecord object. The TM is expected to call getTx() to obtain a reference to the XACommittingTx that will be used to complete the transaction usin putDone() later.
Note that XALogger does not call the TM's listener.getLogRecord().
- Parameters:
listener
- The TM can receive replay events by providing a ReplayListener. TMs that do not wish to see all records during the open replay should pass a null ReplayListener.- Throws:
InvalidFileSetException
LogConfigurationException
InvalidLogBufferException
LogClosedException
java.lang.ClassNotFoundException
java.io.IOException
java.lang.InterruptedException
- See Also:
replayActiveTx(ReplayListener)
-
close
public void close() throws java.io.IOException, java.lang.InterruptedException
Description copied from class:Logger
close the Log files and perform necessary cleanup tasks.
-
getActiveTxUsed
public int getActiveTxUsed()
Used by TM and test cases to obtain the number of entries in the activeTx table.TIP: if value does not agree with expected value in TM or test case, we probably have a bug somewhere.
- Returns:
- current number of used entries in activeTx table
-
activeTxDisplay
public void activeTxDisplay()
displays entries in the activeTx table.useful for debug.
-
replay
public void replay(ReplayListener listener) throws LogConfigurationException
Wrapp Logger#replay(ReplayListener) so we can intercept onRecord() notifications to process XACOMMIT and XACOMMITMOVED records.- Overrides:
replay
in classLogger
- Parameters:
listener
- an object that implements ReplayListener interface.- Throws:
LogConfigurationException
- most likely because the configured LogBuffer class cannot be found.- See Also:
Logger.replay(ReplayListener, long)
-
replay
public void replay(ReplayListener listener, long key) throws InvalidLogKeyException, LogConfigurationException
Wrapp Logger#replay(ReplayListener, long) so we can intercept onRecord() notifications to process XACOMMIT and XACOMMITMOVED records.- Overrides:
replay
in classLogger
- Parameters:
listener
- an object that implements ReplayListener interface.key
- a log key to begin replay from.The mark should be a valid log key returned by the put() method. To replay the entire log beginning with the oldest available record, mark should be set to zero (0L).
- Throws:
InvalidLogKeyException
- if mark is not a valid log key.LogConfigurationException
- most likely because the configured LogBuffer class cannot be found.
-
replayActiveTx
public void replayActiveTx(ReplayListener listener)
Called by the TM to receive copies of the active transaction entries.TMs can use this method as an alternative to passing a ReplayListener to open. The advantage is that only active transaction entries are returned to the ReplayListener.onRecord() method.
- Parameters:
listener
- The activeTx entries are passed to the TM through this ReplayListener.
-
-