comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:3dc0c5604566
1 package org.dancres.blitz.txn;
2
3 import java.rmi.RemoteException;
4 import java.rmi.NoSuchObjectException;
5
6 import java.util.List;
7 import java.util.Iterator;
8
9 import java.util.logging.Level;
10
11 import net.jini.core.transaction.UnknownTransactionException;
12
13 import net.jini.config.ConfigurationException;
14
15 import org.dancres.blitz.ActiveObject;
16 import org.dancres.blitz.ActiveObjectRegistry;
17
18 import org.dancres.blitz.config.ConfigurationFactory;
19
20 /**
21 <p>An instance of this class is created by <code>TransactionManager</code>
22 once recovery has been completed. It's purpose is to regularly check known
23 remote transactions status and abort any that can be declared "dead" as
24 a result of specific results from invoking the remote
25 <code>TransactionManager</code>'s <code>getState</code> method.</p>
26 */
27 class TxnPinger implements ActiveObject, Runnable {
28 private static final String PING_PAUSE = "txnPingInterval";
29
30 static final long NO_PAUSE = -1;
31
32 private long thePause = NO_PAUSE;
33 private Thread theThread;
34 private TxnManagerState theState;
35
36 TxnPinger(TxnManagerState aState) {
37 try {
38 thePause =
39 ((Long)
40 ConfigurationFactory.getEntry(PING_PAUSE,
41 long.class,
42 new Long(NO_PAUSE))).longValue();
43 } catch (ConfigurationException anE) {
44 TxnManager.theLogger.log(Level.SEVERE,
45 "Failed to load txn ping interval",
46 anE);
47 }
48
49 if (thePause != NO_PAUSE) {
50 TxnManager.theLogger.log(Level.INFO, "Txn Pinger active with: " +
51 thePause + " ms");
52 ActiveObjectRegistry.add(this);
53 }
54 }
55
56 public void begin() {
57 theThread = new Thread(this, "TxnPinger");
58 theThread.setDaemon(true);
59 theThread.start();
60 }
61
62 public void halt() {
63 theThread.interrupt();
64 }
65
66 public void run() {
67 while (true) {
68 try {
69 Thread.sleep(thePause);
70 } catch (InterruptedException anIE) {
71 return;
72 }
73
74
75 Iterator myTxnIds = theState.getActiveTxnIds().iterator();
76
77 while (myTxnIds.hasNext()) {
78 TxnId myId = (TxnId) myTxnIds.next();
79
80 // Skip local transactions
81 //
82 if (myId.isNull())
83 continue;
84
85 /*
86 NoSuchObjectException or UnknownTransactionException means
87 we can kill this transaction.
88 */
89 try {
90 TxnGateway myGateway = TxnManager.get().getGateway();
91
92 myGateway.getState(myId);
93 } catch (RemoteException anRE) {
94 if (anRE instanceof NoSuchObjectException) {
95 attemptAbort(myId);
96 }
97 } catch (UnknownTransactionException aUTE) {
98 attemptAbort(myId);
99 }
100 }
101 }
102 }
103
104 private void attemptAbort(TxnId anId) {
105 TxnManager myManager = TxnManager.get();
106
107 try {
108 myManager.abort(myManager.getTxnFor(anId));
109 } catch (Exception anE) {
110 // Nothing more to do, try again next time
111 TxnManager.theLogger.log(Level.SEVERE,
112 "Attempted to abort dead transaction: " +
113 anId, anE);
114 }
115 }
116 }