1 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 ; 41 import java.io.InputStream ; 42 import java.io.NotSerializableException ; 43 import java.io.ObjectInputStream ; 44 import java.io.ObjectOutputStream ; 45 import java.io.ObjectStreamClass ; 46 import java.util.logging.Level ; 47 import java.util.logging.Logger ; 48 49 52 public class ClusterObject { 53 private static final Logger log = Log.open(ClusterObject.class); 54 55 private final StoreManager _storeManager; 56 private final Store _store; 57 private final String _storeId; 58 private final String _objectId; 59 60 private final String _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 private boolean _isValid = true; 76 private boolean _isChanged = false; 77 private boolean _isDead = false; 78 79 ClusterObject(StoreManager storeManager, 80 Store store, 81 String 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 storeId, 99 String 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 private boolean isPrimary(String 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 136 public Store getStore() 137 { 138 return _store; 139 } 140 141 144 public StoreManager getStoreManager() 145 { 146 return _storeManager; 147 } 148 149 152 public String getStoreId() 153 { 154 return _storeId; 155 } 156 157 160 public String getObjectId() 161 { 162 return _objectId; 163 } 164 165 168 public String getUniqueId() 169 { 170 return _uniqueId; 171 } 172 173 176 public long getMaxIdleTime() 177 { 178 return _maxIdleTime; 179 } 180 181 184 public void setMaxIdleTime(long maxIdleTime) 185 { 186 _maxIdleTime = maxIdleTime; 187 } 188 189 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 205 public void setPrimary(boolean primary) 206 { 207 _isPrimary = primary; 208 } 209 210 213 long getCRC() 214 { 215 return _crc; 216 } 217 218 221 void setCRC(long crc) 222 { 223 _crc = crc; 224 } 225 226 229 boolean isValid() 230 { 231 return _isValid; 232 } 233 234 237 void setValid(boolean isValid) 238 { 239 _isValid = isValid; 240 } 241 242 245 public void setValid() 246 { 247 _isValid = true; 248 } 249 250 256 public boolean load(Object obj) 257 { 258 if (! _isSerializable) 259 return true; 260 261 if (_isDead) 262 throw new IllegalStateException (); 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 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 290 boolean load(InputStream is, Object obj) 291 throws IOException 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 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 317 public void update() 318 { 319 _isValid = false; 320 } 321 322 326 public void change() 327 { 328 _isChanged = true; 329 } 330 331 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 e) { 342 log.log(Level.WARNING, e.toString(), e); 343 } 344 345 _accessTime = now; 346 } 347 } 348 349 352 public void setAccessTime(long accessTime) 353 { 354 _accessTime = accessTime; 355 } 356 357 360 public long getExpireInterval() 361 { 362 return _expireInterval; 363 } 364 365 368 public void setExpireInterval(long expireInterval) 369 { 370 try { 371 _expireInterval = expireInterval; 372 373 _storeManager.setExpireInterval(getUniqueId(), expireInterval); 374 } catch (Exception e) { 375 log.log(Level.WARNING, e.toString(), e); 376 } 377 } 378 379 382 public void store(Object obj) 383 throws IOException 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 out = new ObjectOutputStream (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 _storeManager.store(this, tempStream, crc); 424 426 if (_isPrimary) 427 _isValid = true; 428 429 _accessTime = Alarm.getCurrentTime(); 430 } catch (NotSerializableException e) { 431 log.warning(e.toString()); 432 _isSerializable = false; 433 } catch (Throwable 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 446 public void write(InputStream is) 447 throws IOException 448 { 449 } 450 451 454 public ReadStream openRead() 455 throws IOException 456 { 457 return null; 458 } 459 460 463 public void remove() 464 { 465 try { 466 if (_isDead) 467 return; 468 _isDead = true; 469 470 _storeManager.remove(this); 471 } catch (Throwable e) { 472 log.log(Level.WARNING, e.toString(), e); 473 } 474 } 475 476 479 public void removeImpl() 480 { 481 } 482 483 static class DistributedObjectInputStream extends ObjectInputStream { 484 DistributedObjectInputStream(InputStream is) 485 throws IOException 486 { 487 super(is); 488 } 489 490 protected Class resolveClass(ObjectStreamClass v) 491 throws IOException , ClassNotFoundException 492 { 493 String name = v.getName(); 494 495 Thread thread = Thread.currentThread(); 496 ClassLoader loader = thread.getContextClassLoader(); 497 498 return Class.forName(name, false, loader); 499 } 500 } 501 } 502 | Popular Tags |