/** * Sends the first dirty for a received reference in order to get the * appropiate lease time from the server, and then schedules the dirty call * for lease renewal. If the first dirty message fails, a clean "strong" * message is sent for that remote object. If the first dirty call * succeeded, the reference becomes a "live" reference for the client DGC. * * @param ref * The reference received inside the stub * @return The <code>Endpoint / ObjID</code> pair contained inside the * reference * @throws UnmarshalException * If the first dirty call fails */ private final Pair<Endpoint, ObjID> activateReference(RemoteRef ref) throws UnmarshalException { // Get necessary data previously stored during RemoteRef // deserialization. Pair<Endpoint, ObjID> data = deserializedRemoteRefTable.get(ref); if (data == null) { throw new UnmarshalException( "Impossible to get a stub for this object."); } Lease lease = sendDirty(data.getFirst(), new ObjID[] { data.getSecond() }); if (lease != null) { enqueueDirtyCall(data, lease.getValue()); liveReferences.put(data, new Long(lease.getValue())); return data; } else { sendClean(data.getFirst(), new ObjID[] { data.getSecond() }, true); throw new UnmarshalException( "Impossible to get a stub for this object."); } }
/** * Sends a dirty call to the DGC of the remote server, and returns the * <code>Lease</code> granted by that DGC. * * @param ep * The <code>Endpoint</code> where the dirty call will be sent. * @param obj * An array containing the object identifiers that will be sent * in the dirty call. * @return The <code>Lease</code> returned from the server DGC, or * <code>null</code> if the call has failed. */ Lease sendDirty(Endpoint ep, ObjID[] obj) { synchronized(dgcObjID) { Lease lease = new Lease(vmID, leaseValue); Object[] args = new Object[] { obj, ++sequenceNumber, lease }; TransportManager tm = TransportManager.getTransportManager(); Object response; try { response = tm.invoke(dgcObjID, ep, args, SEND_DIRTY_OP_NUM, true); if (response instanceof Lease) { if (vmID == null) { vmID = ((Lease) response).getVMID(); } return (Lease) response; } return null; } catch (Exception e) { return null; } } }
/** * ObjectInputFilter to filter DGC input objects. * The list of acceptable classes is very short and explicit. * The depth and array sizes are limited. * * @param filterInfo access to class, arrayLength, etc. * @return {@link ObjectInputFilter.Status#ALLOWED} if allowed, * {@link ObjectInputFilter.Status#REJECTED} if rejected, * otherwise {@link ObjectInputFilter.Status#UNDECIDED} */ private static ObjectInputFilter.Status checkInput(ObjectInputFilter.FilterInfo filterInfo) { if (dgcFilter != null) { ObjectInputFilter.Status status = dgcFilter.checkInput(filterInfo); if (status != ObjectInputFilter.Status.UNDECIDED) { // The DGC filter can override the built-in white-list return status; } } if (filterInfo.depth() > DGC_MAX_DEPTH) { return ObjectInputFilter.Status.REJECTED; } Class<?> clazz = filterInfo.serialClass(); if (clazz != null) { while (clazz.isArray()) { if (filterInfo.arrayLength() >= 0 && filterInfo.arrayLength() > DGC_MAX_ARRAY_SIZE) { return ObjectInputFilter.Status.REJECTED; } // Arrays are allowed depending on the component type clazz = clazz.getComponentType(); } if (clazz.isPrimitive()) { // Arrays of primitives are allowed return ObjectInputFilter.Status.ALLOWED; } return (clazz == ObjID.class || clazz == UID.class || clazz == VMID.class || clazz == Lease.class) ? ObjectInputFilter.Status.ALLOWED : ObjectInputFilter.Status.REJECTED; } // Not a class, not size limited return ObjectInputFilter.Status.UNDECIDED; }
/** * ObjectInputFilter to filter DGCClient return value (a Lease). * The list of acceptable classes is very short and explicit. * The depth and array sizes are limited. * * @param filterInfo access to class, arrayLength, etc. * @return {@link ObjectInputFilter.Status#ALLOWED} if allowed, * {@link ObjectInputFilter.Status#REJECTED} if rejected, * otherwise {@link ObjectInputFilter.Status#UNDECIDED} */ private static ObjectInputFilter.Status leaseFilter(ObjectInputFilter.FilterInfo filterInfo) { if (filterInfo.depth() > DGCCLIENT_MAX_DEPTH) { return ObjectInputFilter.Status.REJECTED; } Class<?> clazz = filterInfo.serialClass(); if (clazz != null) { while (clazz.isArray()) { if (filterInfo.arrayLength() >= 0 && filterInfo.arrayLength() > DGCCLIENT_MAX_ARRAY_SIZE) { return ObjectInputFilter.Status.REJECTED; } // Arrays are allowed depending on the component type clazz = clazz.getComponentType(); } if (clazz.isPrimitive()) { // Arrays of primitives are allowed return ObjectInputFilter.Status.ALLOWED; } return (clazz == UID.class || clazz == VMID.class || clazz == Lease.class) ? ObjectInputFilter.Status.ALLOWED : ObjectInputFilter.Status.REJECTED; } // Not a class, not size limited return ObjectInputFilter.Status.UNDECIDED; }
/** * Shedule the renewing call, taking into consideration that the following * lease was granted. * * @param lease the lease that was granted. */ public void schedule(Lease lease) { long value = lease.getValue(); // Shedule a 10 % earlier because some time is needed for the message // to reach the server. long reduced = (value * 90)/100; if (reduced == 0) reduced = value; timer.schedule(new LeaseTimerTask(), reduced); }
/** * Renew the lease. */ public void renew() { Object renewIt = null; // Iterate throw the list of associated references. If all are // discarded, there is no need to renew. synchronized (ref) { Iterator iter = ref.iterator(); WeakReference w; while (iter.hasNext() && renewIt == null) { w = (WeakReference) iter.next(); renewIt = w.get(); if (renewIt == null) // Discard the weak reference if its target has been garbage // collected. iter.remove(); } } if (renewIt!=null) { Lease lease = notifyDGC( (UnicastRef) renewIt); // Schedule the next renewing session. if (lease!=null) schedule(lease); } { // All references collected - discard this entry. } }
/** * Notify DGC that we still hold this reference. * * @param renewIt the reference we still have (must not be null). */ public Lease notifyDGC(UnicastRef renewIt) { try { return renewIt.notifyDGC(lease); } catch (Exception e) { // Failed to notify. // TODO Take some relevant action in the case if we failed // to notify the remote object owner. return null; } }
void dgcDirty() { ObjID[] ids; synchronized (tablesLock) { ids = (ObjID[]) renewTable.keySet().toArray( new ObjID[renewTable.size()]); } try { Lease lease = dgcStub.dirty(ids, getSeqNumber(), new Lease(vmid, DGCImpl.maxDuration)); failedDirtyCallsNum = 0; failureStartTime = 0; latestLeaseDuration = lease.getValue(); renewTime = System.currentTimeMillis() + latestLeaseDuration / 2; } catch (RemoteException re) { // dirty call failed long curTime = System.currentTimeMillis(); ++failedDirtyCallsNum; if (failedDirtyCallsNum == 1) { failureStartTime = curTime; latestLeaseDuration = (latestLeaseDuration > 0) ? latestLeaseDuration : DGCImpl.maxDuration; failedRenewBaseDuration = latestLeaseDuration >> 5; } renewTime = curTime + failedRenewBaseDuration * ((failedDirtyCallsNum - 1) << 1); if (renewTime > failureStartTime + latestLeaseDuration) { renewTime = Long.MAX_VALUE; } } }
public void testGetValueAndGetVMID() { VMID vmid = new VMID(); long duration = (long) Math.random() * Long.MAX_VALUE; Lease lease = new Lease(vmid, duration); assertEquals(duration, lease.getValue()); assertEquals(vmid, lease.getVMID()); }
public void testLease001() { long duration = 0; assertNotNull(msgNotNull, new Lease(id, duration)); }
public void testLease002() { id = new VMID(); long duration = 0; assertNotNull(msgNotNull, new Lease(id, duration)); }
public void testLease003() { long duration = Long.MAX_VALUE; assertNotNull(msgNotNull, new Lease(id, duration)); }
public void testLease004() { id = new VMID(); long duration = Long.MAX_VALUE; assertNotNull(msgNotNull, new Lease(id, duration)); }
public void testLease005() { long duration = Long.MIN_VALUE; assertNotNull(msgNotNull, new Lease(id, duration)); }
public void testLease006() { id = new VMID(); long duration = Long.MIN_VALUE; assertNotNull(msgNotNull, new Lease(id, duration)); }
public void testLease007() { long duration = 57690; assertNotNull(msgNotNull, new Lease(id, duration)); }
public void testLease008() { id = new VMID(); long duration = 57690; assertNotNull(msgNotNull, new Lease(id, duration)); }
public void testLease009() { long duration = -57689; assertNotNull(msgNotNull, new Lease(id, duration)); }
public void testLease010() { id = new VMID(); long duration = -57689; assertNotNull(msgNotNull, new Lease(id, duration)); }
public void testGetVMID001() { long duration = 0; l = new Lease(id, duration); assertNull(l.getVMID()); }
public void testGetVMID002() { id = new VMID(); long duration = 0; l = new Lease(id, duration); assertNotNull(l.getVMID()); }
public void testGetVMID003() { long duration = Long.MAX_VALUE; l = new Lease(id, duration); assertNull(l.getVMID()); }
public void testGetVMID004() { id = new VMID(); long duration = Long.MAX_VALUE; l = new Lease(id, duration); assertNotNull(l.getVMID()); }