diff src/org/dancres/blitz/txn/TxnPinger.java @ 0:3dc0c5604566

Initial checkin of blitz 2.0 fcs - no installer yet.
author Dan Creswell <dan.creswell@gmail.com>
date Sat, 21 Mar 2009 11:00:06 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/dancres/blitz/txn/TxnPinger.java	Sat Mar 21 11:00:06 2009 +0000
@@ -0,0 +1,116 @@
+package org.dancres.blitz.txn;
+
+import java.rmi.RemoteException;
+import java.rmi.NoSuchObjectException;
+
+import java.util.List;
+import java.util.Iterator;
+
+import java.util.logging.Level;
+
+import net.jini.core.transaction.UnknownTransactionException;
+
+import net.jini.config.ConfigurationException;
+
+import org.dancres.blitz.ActiveObject;
+import org.dancres.blitz.ActiveObjectRegistry;
+
+import org.dancres.blitz.config.ConfigurationFactory;
+
+/**
+   <p>An instance of this class is created by <code>TransactionManager</code>
+   once recovery has been completed.  It's purpose is to regularly check known
+   remote transactions status and abort any that can be declared "dead" as
+   a result of specific results from invoking the remote
+   <code>TransactionManager</code>'s <code>getState</code> method.</p>
+ */
+class TxnPinger implements ActiveObject, Runnable {
+    private static final String PING_PAUSE = "txnPingInterval";
+
+    static final long NO_PAUSE = -1;
+
+    private long thePause = NO_PAUSE;
+    private Thread theThread;
+    private TxnManagerState theState;
+
+    TxnPinger(TxnManagerState aState) {
+        try {
+            thePause =
+                ((Long)
+                 ConfigurationFactory.getEntry(PING_PAUSE,
+                                               long.class,
+                                               new Long(NO_PAUSE))).longValue();
+        } catch (ConfigurationException anE) {
+            TxnManager.theLogger.log(Level.SEVERE,
+                                     "Failed to load txn ping interval",
+                                     anE);
+        }
+
+        if (thePause != NO_PAUSE) {
+            TxnManager.theLogger.log(Level.INFO, "Txn Pinger active with: " +
+                                     thePause + " ms");
+            ActiveObjectRegistry.add(this);
+        }
+    }
+
+    public void begin() {
+        theThread = new Thread(this, "TxnPinger");
+        theThread.setDaemon(true);
+        theThread.start();
+    }
+
+    public void halt() {
+        theThread.interrupt();
+    }
+
+    public void run() {
+        while (true) {
+            try {
+                Thread.sleep(thePause);
+            } catch (InterruptedException anIE) {
+                return;
+            }
+
+
+            Iterator myTxnIds = theState.getActiveTxnIds().iterator();
+
+            while (myTxnIds.hasNext()) {
+                TxnId myId = (TxnId) myTxnIds.next();
+
+                // Skip local transactions
+                //
+                if (myId.isNull())
+                    continue;
+
+                /*
+                   NoSuchObjectException or UnknownTransactionException means
+                   we can kill this transaction.
+                 */
+                try {
+                    TxnGateway myGateway = TxnManager.get().getGateway();
+
+                    myGateway.getState(myId);
+                } catch (RemoteException anRE) {
+                    if (anRE instanceof NoSuchObjectException) {
+                        attemptAbort(myId);
+                    }
+                } catch (UnknownTransactionException aUTE) {
+                        attemptAbort(myId);
+                }
+            }
+        }
+    }
+
+    private void attemptAbort(TxnId anId) {
+        TxnManager myManager = TxnManager.get();
+
+        try {
+            myManager.abort(myManager.getTxnFor(anId));
+        } catch (Exception anE) {
+            // Nothing more to do, try again next time
+            TxnManager.theLogger.log(Level.SEVERE,
+                                     "Attempted to abort dead transaction: " +
+                                     anId, anE);
+        }
+    }
+}
\ No newline at end of file