KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > server > cluster > ClusterObject


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.server.cluster;
31
32 import com.caucho.log.Log;
33 import com.caucho.util.Alarm;
34 import com.caucho.vfs.Crc64Stream;
35 import com.caucho.vfs.ReadStream;
36 import com.caucho.vfs.TempStream;
37 import com.caucho.vfs.VfsStream;
38 import com.caucho.vfs.WriteStream;
39
40 import java.io.IOException JavaDoc;
41 import java.io.InputStream JavaDoc;
42 import java.io.NotSerializableException JavaDoc;
43 import java.io.ObjectInputStream JavaDoc;
44 import java.io.ObjectOutputStream JavaDoc;
45 import java.io.ObjectStreamClass JavaDoc;
46 import java.util.logging.Level JavaDoc;
47 import java.util.logging.Logger JavaDoc;
48
49 /**
50  * Data for the cluster's object.
51  */

52 public class ClusterObject {
53   private static final Logger JavaDoc log = Log.open(ClusterObject.class);
54
55   private final StoreManager _storeManager;
56   private final Store _store;
57   private final String JavaDoc _storeId;
58   private final String JavaDoc _objectId;
59
60   private final String JavaDoc _uniqueId;
61
62   private ObjectManager _objectManager;
63
64   private boolean _isPrimary;
65   private long _maxIdleTime;
66   
67   private long _expireInterval = -1;
68
69   private long _accessTime;
70
71   private long _crc = -1;
72
73   private boolean _isSerializable = true;
74   // true if the current data is valid and up to date
75
private boolean _isValid = true;
76   private boolean _isChanged = false;
77   private boolean _isDead = false;
78
79   ClusterObject(StoreManager storeManager,
80         Store store,
81         String JavaDoc objectId)
82   {
83     _storeManager = storeManager;
84     _objectManager = store.getObjectManager();
85     _store = store;
86     _maxIdleTime = _store.getMaxIdleTime();
87
88     _storeId = store.getId();
89     _objectId = objectId;
90     _uniqueId = _storeId + ';' + objectId;
91
92     _isPrimary = isPrimary(_objectId);
93     
94     _expireInterval = getMaxIdleTime() + getAccessWindow();
95   }
96
97   ClusterObject(StoreManager storeManager,
98         String JavaDoc storeId,
99         String JavaDoc objectId)
100   {
101     _storeManager = storeManager;
102     _objectManager = null;
103     _store = null;
104
105     _maxIdleTime = _storeManager.getMaxIdleTime();
106
107     _storeId = storeId;
108     _objectId = objectId;
109     _uniqueId = _storeId + ';' + objectId;
110
111     _isPrimary = isPrimary(_objectId);
112
113     _expireInterval = getMaxIdleTime() + getAccessWindow();
114   }
115
116   public void setObjectManager(ObjectManager objectManager)
117   {
118     _objectManager = objectManager;
119   }
120
121   // XXX: move to store manager?
122
private boolean isPrimary(String JavaDoc id)
123   {
124     if (_store != null && _store.isAlwaysLoad())
125       return false;
126     
127     else if (_store == null && _storeManager.isAlwaysLoad())
128       return false;
129
130     return _storeManager.isPrimary(id);
131   }
132
133   /**
134    * Returns the store.
135    */

136   public Store getStore()
137   {
138     return _store;
139   }
140
141   /**
142    * Returns the store manager.
143    */

144   public StoreManager getStoreManager()
145   {
146     return _storeManager;
147   }
148
149   /**
150    * Returns the store id.
151    */

152   public String JavaDoc getStoreId()
153   {
154     return _storeId;
155   }
156
157   /**
158    * Returns the object id.
159    */

160   public String JavaDoc getObjectId()
161   {
162     return _objectId;
163   }
164
165   /**
166    * Returns the unique id.
167    */

168   public String JavaDoc getUniqueId()
169   {
170     return _uniqueId;
171   }
172
173   /**
174    * Returns the max idle time.
175    */

176   public long getMaxIdleTime()
177   {
178     return _maxIdleTime;
179   }
180
181   /**
182    * Sets the max idle time.
183    */

184   public void setMaxIdleTime(long maxIdleTime)
185   {
186     _maxIdleTime = maxIdleTime;
187   }
188
189   /**
190    * Returns the access window.
191    */

192   public long getAccessWindow()
193   {
194     long window = _maxIdleTime / 4;
195
196     if (window < 60000L)
197       return 60000L;
198     else
199       return window;
200   }
201
202   /**
203    * Sets true for the primary server.
204    */

205   public void setPrimary(boolean primary)
206   {
207     _isPrimary = primary;
208   }
209
210   /**
211    * Returns the object's saved CRC value.
212    */

213   long getCRC()
214   {
215     return _crc;
216   }
217
218   /**
219    * Sets the object's saved CRC value.
220    */

221   void setCRC(long crc)
222   {
223     _crc = crc;
224   }
225
226   /**
227    * Returns true if the object has up-to-date loaded values
228    */

229   boolean isValid()
230   {
231     return _isValid;
232   }
233
234   /**
235    * Sets the object's saved update count
236    */

237   void setValid(boolean isValid)
238   {
239     _isValid = isValid;
240   }
241
242   /**
243    * Sets the object's saved update count
244    */

245   public void setValid()
246   {
247     _isValid = true;
248   }
249
250   /**
251    * Loads the object from the cluster. If the object fails to load,
252    * its contents may be in an inconsistent state.
253    *
254    * @return true on success.
255    */

256   public boolean load(Object JavaDoc obj)
257   {
258     if (! _isSerializable)
259       return true;
260
261     if (_isDead)
262       throw new IllegalStateException JavaDoc();
263
264     if (_isPrimary && _isValid)
265       return true;
266
267     try {
268       if (_storeManager.load(this, obj)) {
269     _isValid = true;
270     
271     return true;
272       }
273       else {
274     _crc = -1;
275     return false;
276       }
277     } catch (Exception JavaDoc e) {
278       log.log(Level.WARNING, e.toString(), e);
279       _crc = -1;
280
281       return false;
282     } finally {
283       _isChanged = false;
284     }
285   }
286
287   /**
288    * Loads the object, called from the store.
289    */

290   boolean load(InputStream JavaDoc is, Object JavaDoc obj)
291     throws IOException JavaDoc
292   {
293     VfsStream streamImpl = new VfsStream(is, null);
294
295     Crc64Stream crcStream = new Crc64Stream(streamImpl);
296
297     ReadStream crcIs = new ReadStream(crcStream);
298
299     ObjectInputStream JavaDoc in = new DistributedObjectInputStream(crcIs);
300
301     _objectManager.load(in, obj);
302
303     _isValid = true;
304     _crc = crcStream.getCRC();
305
306     in.close();
307     crcIs.close();
308
309     return true;
310   }
311
312   /**
313    * Signals that the object has been updated externally, i.e.
314    * that the persistent store now has a more current version of
315    * the object's data.
316    */

317   public void update()
318   {
319     _isValid = false;
320   }
321
322   /**
323    * Signals that the object has been changed by the application, i.e.
324    * that the object needs to be saved to the persistent store.
325    */

326   public void change()
327   {
328     _isChanged = true;
329   }
330
331   /**
332    * Marks the object as accessed.
333    */

334   public void access()
335   {
336     long now = Alarm.getCurrentTime();
337
338     if (getAccessWindow() <= now - _accessTime) {
339       try {
340     _storeManager.accessImpl(getUniqueId());
341       } catch (Exception JavaDoc e) {
342     log.log(Level.WARNING, e.toString(), e);
343       }
344
345       _accessTime = now;
346     }
347   }
348
349   /**
350    * Sets the access time.
351    */

352   public void setAccessTime(long accessTime)
353   {
354     _accessTime = accessTime;
355   }
356
357   /**
358    * Sets the max access time.
359    */

360   public long getExpireInterval()
361   {
362     return _expireInterval;
363   }
364
365   /**
366    * Sets the max access time.
367    */

368   public void setExpireInterval(long expireInterval)
369   {
370     try {
371       _expireInterval = expireInterval;
372       
373       _storeManager.setExpireInterval(getUniqueId(), expireInterval);
374     } catch (Exception JavaDoc e) {
375       log.log(Level.WARNING, e.toString(), e);
376     }
377   }
378
379   /**
380    * Saves the object to the cluster.
381    */

382   public void store(Object JavaDoc obj)
383     throws IOException JavaDoc
384   {
385     if (! _isSerializable)
386       return;
387
388     boolean isValid = _isValid;
389
390     if (! _isPrimary) {
391       _isValid = false;
392     }
393
394     if (! _isChanged && ! _store.isAlwaysSave())
395       return;
396
397     _isChanged = false;
398
399     TempStream tempStream = new TempStream(null);
400     Crc64Stream crcStream = new Crc64Stream(tempStream);
401
402     try {
403       WriteStream os = new WriteStream(crcStream);
404
405       ObjectOutputStream JavaDoc out = new ObjectOutputStream JavaDoc(os);
406
407       _objectManager.store(out, obj);
408
409       out.flush();
410       long crc = crcStream.getCRC();
411
412       out.close();
413
414       os.close();
415       os = null;
416
417       if (crc == _crc)
418     return;
419
420       _crc = crc;
421
422       //System.oout.println("STORING: " + _uniqueId);
423
_storeManager.store(this, tempStream, crc);
424       //System.out.println("STORED: " + _uniqueId);
425

426       if (_isPrimary)
427     _isValid = true;
428
429       _accessTime = Alarm.getCurrentTime();
430     } catch (NotSerializableException JavaDoc e) {
431       log.warning(e.toString());
432       _isSerializable = false;
433     } catch (Throwable JavaDoc e) {
434       log.warning(e.toString());
435       log.log(Level.FINE, e.toString(), e);
436
437       _isValid = false;
438     } finally {
439       tempStream.destroy();
440     }
441   }
442
443   /**
444    * Writes updated values
445    */

446   public void write(InputStream JavaDoc is)
447     throws IOException JavaDoc
448   {
449   }
450
451   /**
452    * Reads the current value
453    */

454   public ReadStream openRead()
455     throws IOException JavaDoc
456   {
457     return null;
458   }
459
460   /**
461    * Removes the object from the cluster.
462    */

463   public void remove()
464   {
465     try {
466       if (_isDead)
467     return;
468       _isDead = true;
469
470       _storeManager.remove(this);
471     } catch (Throwable JavaDoc e) {
472       log.log(Level.WARNING, e.toString(), e);
473     }
474   }
475
476   /**
477    * Removes the object from the cluster.
478    */

479   public void removeImpl()
480   {
481   }
482
483   static class DistributedObjectInputStream extends ObjectInputStream JavaDoc {
484     DistributedObjectInputStream(InputStream JavaDoc is)
485       throws IOException JavaDoc
486     {
487       super(is);
488     }
489
490     protected Class JavaDoc resolveClass(ObjectStreamClass JavaDoc v)
491       throws IOException JavaDoc, ClassNotFoundException JavaDoc
492     {
493       String JavaDoc name = v.getName();
494
495       Thread JavaDoc thread = Thread.currentThread();
496       ClassLoader JavaDoc loader = thread.getContextClassLoader();
497
498       return Class.forName(name, false, loader);
499     }
500   }
501 }
502
Popular Tags