Mercurial > hg > blitz_condensed
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 } |