comparison src/org/dancres/blitz/remote/txn/LoopBackMgr.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.remote.txn;
2
3 import java.rmi.RemoteException;
4 import java.util.HashMap;
5 import java.util.logging.Logger;
6 import java.util.logging.Level;
7
8 import net.jini.core.transaction.server.ServerTransaction;
9 import net.jini.core.transaction.server.TransactionManager;
10 import net.jini.core.transaction.*;
11 import net.jini.core.lease.LeaseDeniedException;
12 import net.jini.config.ConfigurationException;
13
14 import org.dancres.blitz.txn.TxnManager;
15 import org.dancres.blitz.txn.TxnState;
16 import org.dancres.blitz.util.Time;
17 import org.dancres.blitz.lease.LeaseBounds;
18 import org.dancres.blitz.lease.Reapable;
19 import org.dancres.blitz.lease.ReapFilter;
20 import org.dancres.blitz.lease.LeaseReaper;
21 import org.dancres.blitz.Logging;
22 import org.dancres.blitz.config.ConfigurationFactory;
23
24 /**
25 */
26 public class LoopBackMgr implements Reapable {
27
28 private static Logger theLogger =
29 Logging.newLogger("org.dancres.blitz.remote.txn.LoopBackMgr");
30
31 /**
32 * This will need updating based on reading the log or reading
33 * from checkpoint or both! NO IT WON'T we simply won't log these - they
34 * either complete or they don't - they're one operation wonders which
35 * don't need logging.
36 */
37 private long theNextKey = 0;
38 private long theMagic = System.currentTimeMillis();
39
40 private LeaseReaper theReaper;
41
42 /**
43 * Keeps track of transactions we have active in the core. We hold lease
44 * state here.
45 */
46 private HashMap theActiveTxns = new HashMap();
47
48 private TransactionManager theStub;
49
50 private static LoopBackMgr theMgr;
51
52 static void init(TransactionManager aStub) {
53 theMgr = new LoopBackMgr(aStub);
54 }
55
56 static LoopBackMgr get() {
57 return theMgr;
58 }
59
60 private LoopBackMgr(TransactionManager aStub) {
61 try {
62 long myReapInterval =
63 ((Long) ConfigurationFactory.getEntry("loopbackTxnReapInterval",
64 long.class,
65 new Long(5 * 60 * 1000))).longValue();
66 theReaper = new LeaseReaper("LoopbackTxn", null, myReapInterval);
67
68 theReaper.add(this);
69
70 } catch (ConfigurationException aCE) {
71 theLogger.log(Level.SEVERE, "Failed to load config", aCE);
72 }
73
74 theStub = aStub;
75 }
76
77 private long nextId() {
78 synchronized (this) {
79 return theNextKey++;
80 }
81 }
82
83 public TxnTicket create(long aLeaseTime)
84 throws LeaseDeniedException, RemoteException {
85
86 long myLeaseTime =
87 Time.getAbsoluteTime(LeaseBounds.boundTxn(aLeaseTime));
88
89 long myId = nextId();
90
91 SpaceTxnUID myUID = new SpaceTxnUID(myId, theMagic);
92
93 TxnDetails myDetails = new TxnDetails(myLeaseTime);
94
95 ServerTransaction myTxn = new ServerTransaction(theStub, myId);
96
97 try {
98 // Insert the transaction
99 //
100 TxnManager.get().getTxnFor(myTxn, false);
101 } catch (Exception anE) {
102 theLogger.log(Level.SEVERE, "Failed to allocate loopback txn", anE);
103 throw new LeaseDeniedException("Couldn't allocate txn");
104 }
105
106 synchronized(this) {
107 theActiveTxns.put(myUID, myDetails);
108 }
109
110 return new TxnTicket(myUID, myLeaseTime);
111 }
112
113 private SpaceTxnUID validateTxn(long anId)
114 throws UnknownTransactionException {
115
116 SpaceTxnUID myUID = new SpaceTxnUID(anId, theMagic);
117
118 synchronized (this) {
119 TxnDetails myDetails = (TxnDetails) theActiveTxns.get(myUID);
120
121 if ((myDetails == null) ||
122 (myDetails.hasExpired(System.currentTimeMillis())))
123 throw new UnknownTransactionException();
124 }
125
126 return myUID;
127 }
128
129 public void commit(long id)
130 throws UnknownTransactionException, CannotCommitException,
131 RemoteException {
132
133 SpaceTxnUID myUID = validateTxn(id);
134
135 TxnManager myMgr = TxnManager.get();
136
137 TxnState myState = myMgr.getTxnFor(theStub, id);
138
139 try {
140 myMgr.prepareAndCommit(myState);
141 } finally {
142 synchronized (this) {
143 theActiveTxns.remove(myUID);
144 }
145 }
146 }
147
148 public void commit(long id, long waitFor)
149 throws UnknownTransactionException, CannotCommitException,
150 TimeoutExpiredException, RemoteException {
151
152 commit(id);
153 }
154
155 public void abort(long id)
156 throws UnknownTransactionException, CannotAbortException,
157 RemoteException {
158
159 SpaceTxnUID myUID = validateTxn(id);
160
161 TxnManager myMgr = TxnManager.get();
162
163 TxnState myState = myMgr.getTxnFor(theStub, id);
164
165 try {
166 myMgr.abort(myState);
167 } finally {
168 synchronized(this) {
169 theActiveTxns.remove(myUID);
170 }
171 }
172 }
173
174 public void abort(long id, long waitFor)
175 throws UnknownTransactionException, CannotAbortException,
176 TimeoutExpiredException, RemoteException {
177
178 abort(id);
179 }
180
181 boolean renew(SpaceTxnUID aUID, long anExpiry) {
182 synchronized (this) {
183 TxnDetails myHolder = (TxnDetails) theActiveTxns.get(aUID);
184
185 if (myHolder != null) {
186 return myHolder.testAndSetExpiry(System.currentTimeMillis(),
187 anExpiry);
188 }
189
190 return false;
191 }
192 }
193
194 boolean cancel(SpaceTxnUID aUID) {
195 return (delete(aUID) != null);
196 }
197
198
199 public TxnDetails delete(SpaceTxnUID aUID) {
200
201 synchronized (this) {
202 TxnDetails myHolder = (TxnDetails) theActiveTxns.remove(aUID);
203
204 if (myHolder != null) {
205 try {
206 TxnState myState =
207 TxnManager.get().getTxnFor(theStub, aUID.getId());
208
209 TxnManager.get().abort(myState);
210 } catch (Exception anE) {
211 // Nothing we cn do
212 }
213
214 return myHolder;
215 }
216
217 return null;
218 }
219 }
220
221 public void reap(ReapFilter aFilter) {
222 /*
223 No reap filters will be configured so we can ignore those - see
224 initialization in constructor
225 */
226 long myTime = System.currentTimeMillis();
227
228 Object[] myKeys;
229
230 synchronized (this) {
231 myKeys = theActiveTxns.keySet().toArray();
232 }
233
234 for (int i = 0; i < myKeys.length; i++) {
235 TxnDetails myHolder =
236 (TxnDetails) theActiveTxns.get(myKeys[i]);
237
238 if (myHolder.hasExpired(myTime)) {
239 delete((SpaceTxnUID) myKeys[i]);
240 }
241 }
242 }
243
244 public String toString() {
245 return "LoopBackMgr";
246 }
247
248 public int hashCode() {
249 return 4095;
250 }
251
252 public boolean equals(Object anObject) {
253 if (anObject instanceof LoopBackMgr)
254 return true;
255 else
256 return false;
257 }
258 }