clusterobject.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 578 行
JAVA
578 行
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */package com.caucho.server.cluster;import com.caucho.util.Alarm;import com.caucho.vfs.*;import java.io.*;import java.util.logging.Level;import java.util.logging.Logger;/** * Data for the cluster's object. */public class ClusterObject { private static final Logger log = Logger.getLogger(ClusterObject.class.getName()); private final HashKey _id; private final HashKey _storeId; private final StoreManager _storeManager; private final Store _store; private Object _objectManagerKey; // key for the object manager private ObjectManager _objectManager; private int _primary; private int _secondary; private int _tertiary; private long _maxIdleTime; private long _expireInterval = -1; private long _accessTime; private byte []_dataHash; // the object's obj is current with the persistent objectStore private boolean _isValid = false; // the object's obj has been modified, but not saved private boolean _isDirty = false; // the object has been removed private boolean _isDead = false; // unserializable objects are skipped private boolean _isSerializable = true; /** * Creates a new cluster object * * @param objectStore the owning objectStore * @param id the object's unique identity * @param primary the primary owning server * @param secondary the secondary backup * @param tertiary the tertiary backup */ ClusterObject(Store store, HashKey id, int primary, int secondary, int tertiary) { _id = id; _storeId = store.getId(); _storeManager = store.getStoreManager(); _objectManager = store.getObjectManager(); _store = store; _maxIdleTime = _store.getMaxIdleTime(); _primary = primary; _secondary = secondary; _tertiary = tertiary; _expireInterval = getMaxIdleTime() + getAccessWindow(); } ClusterObject(StoreManager storeManager, HashKey storeId, HashKey objectId, int primary, int secondary, int tertiary) { _storeManager = storeManager; _objectManager = null; _store = null; _primary = primary; _secondary = secondary; _tertiary = tertiary; _maxIdleTime = _storeManager.getMaxIdleTime(); _storeId = storeId; _id = objectId; _expireInterval = getMaxIdleTime() + getAccessWindow(); } public void setObjectManager(ObjectManager objectManager) { _objectManager = objectManager; } // XXX: move to objectStore manager? public boolean isPrimary() { if (_store != null && _store.isAlwaysLoad()) return false; else if (_store == null && _storeManager.isAlwaysLoad()) return false; Cluster cluster = _storeManager.getCluster(); return cluster.getSelfServer().getIndex() == _primary; } /** * Returns the objectStore. */ public Store getStore() { return _store; } /** * Returns the objectStore manager. */ public StoreManager getStoreManager() { return _storeManager; } /** * Returns the objectStore id. */ public HashKey getStoreId() { return _storeId; } /** * Returns the object id. */ public HashKey getObjectId() { return _id; } /** * Returns the object manager key */ public Object getObjectManagerKey() { return _objectManagerKey; } /** * Sets the object manager key */ public void setObjectManagerKey(Object key) { _objectManagerKey = key; } /** * Sets the objectAccess time. */ public void setAccessTime(long accessTime) { _accessTime = accessTime; } /** * Sets the max objectAccess time. */ public long getExpireInterval() { return _expireInterval; } /** * Sets the max objectAccess time. */ public void setExpireInterval(long expireInterval) { try { _expireInterval = expireInterval; _storeManager.setExpireInterval(getObjectId(), expireInterval); } catch (Exception e) { log.log(Level.WARNING, e.toString(), e); } } /** * Returns the max idle time. */ public long getMaxIdleTime() { return _maxIdleTime; } /** * Sets the max idle time. */ public void setMaxIdleTime(long maxIdleTime) { _maxIdleTime = maxIdleTime; } /** * Returns the objectAccess window. */ public long getAccessWindow() { long window = _maxIdleTime / 4; if (window < 60000L) return 60000L; else return window; } /** * Returns true if the object has up-to-date loaded values */ boolean isValid() { return _isValid; } /** * Returns the primary index for the object */ public int getPrimaryIndex() { return _primary; } /** * Returns the secondary server for the object */ public int getSecondaryIndex() { return _secondary; } /** * Returns the tertiary server for the object */ public int getTertiaryIndex() { return _tertiary; } /** * Returns the primary server for the object */ public ClusterServer getPrimaryServer() { Cluster cluster = _storeManager.getCluster(); ClusterServer []serverList = cluster.getServerList(); if (serverList.length > 1) return serverList[_primary % serverList.length]; else return null; } /** * Returns the secondary server for the object */ public ClusterServer getSecondaryServer() { Cluster cluster = _storeManager.getCluster(); ClusterServer []serverList = cluster.getServerList(); if (serverList.length > 1) return serverList[_secondary % serverList.length]; else return null; } /** * Returns the tertiary server for the object */ public ClusterServer getTertiaryServer() { Cluster cluster = _storeManager.getCluster(); ClusterServer []serverList = cluster.getServerList(); if (serverList.length > 1) return serverList[_tertiary % serverList.length]; else return null; } // // Object API // Called by the object itself (e.g. the session) to invalidate its own state // /** * Called by the object when it is accessed to invalidate the access time. */ public void objectAccess() { long now = Alarm.getCurrentTime(); if (getAccessWindow() <= now - _accessTime) { try { _storeManager.accessImpl(this); } catch (Exception e) { log.log(Level.WARNING, e.toString(), e); } _accessTime = now; } } /** * Called when the object is newly created. */ public void objectCreate() { _isValid = true; } /** * Marks that the object no longer contains valid data */ public void objectInvalidated() { _isValid = false; } /** * Called by the object to load itself from the cluster. * If the object fails to load, its contents may be in an * inconsistent state. * * @return true on success. */ public boolean objectLoad(Object obj) { if (! _isSerializable) return true; if (_isDead) return false; // if the object is valid and the authoritative copy, it can // be returned directly if (_isValid && isPrimary()) return true; try { if (_storeManager.load(this, obj)) { _isValid = true; return true; } else { _dataHash = null; return false; } } catch (Exception e) { log.log(Level.WARNING, e.toString(), e); _dataHash = null; return false; } finally { _isDirty = false; } } /** * Signals that the object has been changed by the application, i.e. * that the object needs to be saved to the persistent objectStore. */ public void objectModified() { _isDirty = true; } /** * Called by the object to remove itself from the cluster. */ public void objectRemove() { try { if (_isDead) return; _isDead = true; _storeManager.remove(this); /* if (_objectManager != null) _objectManager.remove(this); */ } catch (Exception e) { log.log(Level.WARNING, e.toString(), e); } } /** * Called by the object to save itself to the cluster. */ public void objectStore(Object obj) throws IOException { if (! _isSerializable) return; // if the object is not the owner, the value is no longer valid if (! isPrimary()) { _isValid = false; } if (! _isDirty && ! _store.isAlwaysSave()) return; _isDirty = false; TempOutputStream tempStream = new TempOutputStream(); try { DigestOutputStream digestStream = new DigestOutputStream(tempStream); _objectManager.store(digestStream, obj); digestStream.close(); byte []dataHash = digestStream.getDigest(); if (isMatch(dataHash, _dataHash)) return; byte []oldDataHash = _dataHash; _dataHash = dataHash; _storeManager.store(this, tempStream, dataHash, oldDataHash); if (isPrimary()) _isValid = true; _accessTime = Alarm.getCurrentTime(); } catch (NotSerializableException e) { log.warning(e.toString()); _isSerializable = false; } catch (Exception e) { log.log(Level.WARNING, e.toString(), e); _isValid = false; } finally { tempStream.destroy(); } } private static boolean isMatch(byte []a, byte []b) { if (a == null || b == null) return false; int len = a.length; if (len != b.length) return false; for (int i = len - 1; i >= 0; i--) { if (a[i] != b[i]) return false; } return true; } // // Cluster API // Called by the clustering to invalidate the object's state // /** * Loads the object, called from the objectStore. */ boolean loadImpl(InputStream is, Object value, byte []dataHash) throws IOException { _objectManager.load(is, value); _dataHash = dataHash; return true; } /** * Signals that the object has been updated externally, i.e. * that the persistent objectStore now has a more current version of * the object's data. */ public void updateImpl() { _isValid = false; } /** * Called when the object is accessed to updateImpl the objectAccess time. */ public void accessImpl() { long now = Alarm.getCurrentTime(); if (getAccessWindow() <= now - _accessTime) { try { _storeManager.accessImpl(this); } catch (Exception e) { log.log(Level.WARNING, e.toString(), e); } _accessTime = now; } } /** * Removes the object from the cluster. */ public void removeImpl() { if (_objectManager != null && getObjectManagerKey() != null) _objectManager.notifyRemove(getObjectManagerKey()); _isDead = true; // XXX: ? } @Override public String toString() { return getClass().getSimpleName() + "[" + _id + "]"; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?