📄 rdvmonitor.java
字号:
/**
* $Id: RdvMonitor.java,v 1.2 2002/03/04 21:43:00 echtcherbina Exp $
*
* Copyright (c) 2001 Sun Microsystems, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Sun Microsystems, Inc. for Project JXTA."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA"
* must not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact Project JXTA at http://www.jxta.org.
*
* 5. Products derived from this software may not be called "JXTA",
* nor may "JXTA" appear in their name, without prior written
* permission of Sun.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL SUN MICROSYSTEMS OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of Project JXTA. For more
* information on Project JXTA, please see
* <http://www.jxta.org/>.
*
* This license is based on the BSD license adopted by the Apache Foundation.
*/
package net.jxta.impl.rendezvous;
import java.util.*;
import org.apache.log4j.Category; import org.apache.log4j.Priority;
import net.jxta.peer.*;
import net.jxta.protocol.*;
import net.jxta.document.*;
import net.jxta.rendezvous.*;
import net.jxta.discovery.*;
import net.jxta.peergroup.*;
import net.jxta.impl.peergroup.*;
import net.jxta.util.*;
import net.jxta.impl.util.*;
import java.io.*;
/**
* This class implements a very simple RendezVousService Monitor
*/
public class RdvMonitor implements RendezVousMonitor, JxtaTimerHandler {
private final static Category LOG = Category.getInstance(RdvMonitor.class.getName());
// Must start worrying about renewing a lease 10 minutes before it
// expires. Renewal is attempted at each iteration until it is
// either safe again or expired.
private final static long LeaseMargin = 10 * 60 * 1000;
// LeaseRenewalDelay is the period of the timer that will renew the lease
// to the rendezvous. We check every 2 minutes but renew only the
// endangered ones.
// If a rendezvous gives a lease less than that the delay
// this client may lose the lease. A lease of less than 5 minutes does not
// seem to make any sense, since some of the endpoint protocols have at
// least a 2 minutes latency, 2 minutes should be safe enough.
private final static long LeaseRenewalDelay = 2 * 60 * 1000;
private PeerGroup group = null;
private String gId = null;
private DiscoveryService discovery = null;
private long lease = 0;
private JxtaTimer timer = null;
private Vector rdvs = null;
private RendezVousServiceImpl rendezvous = null;
/**
*Constructor for the RdvMonitor object
*
* @param g Description of Parameter
* @param rendezvous Description of Parameter
*/
public RdvMonitor(PeerGroup g, RendezVousServiceImpl rendezvous) {
this.group = g;
this.gId = g.getPeerGroupID().toString();
this.rdvs = new Vector();
this.timer = null;
this.rendezvous = rendezvous;
discovery = group.getDiscoveryService();
if (group.isRendezvous()) {
// This peer is a rendezvous for the group. Let's publish an rdv adv
publishAdv((PeerID) group.getPeerID(), LeaseRenewalDelay);
}
}
/**
* This method is called by the RendezVousService service to notify the
* monitor that a new RendezVousService has accepted the connection.
*
* @param peer is the PeerId of the new connect RendezVousService peer.
* @param lease is the time in millisecond that the RendezVousService is
* ready to serve.
*/
public void connected(PeerID peer, long lease) {
if (LOG.isDebugEnabled() ) {
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("connected: new connection to a RendezVousService");
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug(" peer = " + peer.toString());
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug(" lease = " + lease);
}
addRendezVous(peer.toString(), lease);
// Publish locally an rendezvous advertisement for that rendezvous
publishAdv(peer, lease);
}
/**
* This method is called each time a RendezVousService peer is not
* reachable anymore.
*
* @param peer is the PeerId of the RendezVousService peer.
*/
public void disconnected(PeerID peer) {
if (LOG.isDebugEnabled() ) {
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("disconnected with RendezVousService");
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug(" peerId = " + peer.toString());
}
}
/**
* This method is called by the RendezVousService service in order
* to provide advertisement about other RendezVousService peers.
* This is usefull when a RendezVousService peer wants to balance its load
* to other RendezVousService
*
* @param adv Description of Parameter
*/
public void discovered(Advertisement adv) {
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("discovered: got new RendezVousService advertisement.");
// Publish the rendez vous advertisement
// First publish the advertisement
if (discovery != null) {
try {
discovery.publish(adv, DiscoveryService.ADV);
} catch (Exception e) {
}
}
}
/**
*Description of the Method
*
* @param timer Description of Parameter
*/
public synchronized void signal(JxtaTimer timer) {
if (group.isRendezvous()) {
// This peer is a rendezvous for the group. Let's publish an rdv adv
publishAdv((PeerID) group.getPeerID(), LeaseRenewalDelay);
}
if (rdvs == null) {
return;
}
RdV rdv = null;
for (int i = 0; i < rdvs.size(); ++i) {
try {
rdv = (RdV) rdvs.elementAt(i);
if (rdv.lease - System.currentTimeMillis() < LeaseMargin) {
rendezvous.reconnectToRendezVous(rdv.peer);
}
} catch (Exception e) {
continue;
}
}
}
/**
*Adds a feature to the RendezVousService attribute of the RdvMonitor object
*
* @param peer The feature to be added to the RendezVousService attribute
* @param lease The feature to be added to the RendezVousService attribute
*/
private synchronized void addRendezVous(String peer, long lease) {
RdV rdv = new RdV(peer);
if (rdvs.contains(rdv)) {
// This is only a confirmation of a renewal of the lease.
try {
int index = rdvs.indexOf(rdv);
if (index == -1) {
// This should not happen
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("addRendezVous cannot access RdV object");
return;
}
rdv = (RdV) rdvs.elementAt(index);
} catch (Exception e) {
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("addRendez failed [1] " + e);
}
} else {
// This is a new Rendezvous
rdvs.addElement(rdv);
}
// Set the lease
long time = System.currentTimeMillis();
if ( lease < 0) {
// The rendez has given an infinite lease.
// However, it is a good thing to still renew the lease once in a while
lease = 60 * 60 * 1000;
// 1 Hour
}
rdv.lease = time + lease;
// Check if the timer thread is already started
if (timer == null) {
timer = new JxtaTimer(this, LeaseRenewalDelay, true);
}
}
/**
*Description of the Method
*
* @param gid Description of Parameter
* @param rdvid Description of Parameter
* @param timeout Description of Parameter
* @return Description of the Returned Value
*/
private RdvAdvertisement createRdvAdv(PeerGroupID gid,
PeerID rdvid,
long timeout) {
RdvAdvertisement adv = null;
try {
// Create a rendezvous advertisement
adv = (RdvAdvertisement)
AdvertisementFactory.newAdvertisement(
RdvAdvertisement.getAdvertisementType());
} catch (Exception all) {
if (LOG.isEnabledFor(Priority.WARN)) LOG.warn("Advertisement document could not be created");
return null;
}
adv.setGroupID(gid);
adv.setPeerID(rdvid);
return adv;
}
protected void startRdv() {
publishAdv((PeerID) group.getPeerID(), LeaseRenewalDelay);
}
/**
*Description of the Method
*
* @param pid Description of Parameter
* @param lease Description of Parameter
*/
private void publishAdv(PeerID pid, long lease) {
if (LOG.isDebugEnabled() ) {
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("Publish RdvAdvertisement:");
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug(" gid = " + group.getPeerGroupID().toString());
if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug(" pid = " + pid.toString());
}
RdvAdvertisement rdv =
createRdvAdv((PeerGroupID) group.getPeerGroupID(),
pid,
lease);
if (rdv == null) {
return;
}
// Publish into the parent group.
RefPeerGroup parent = ((GenericPeerGroup) group).getParentGroup();
if (parent == null) {
// No parent... nothing to do.
return;
}
DiscoveryService parentDiscovery = parent.getDiscoveryService();
if (parentDiscovery == null) {
if (LOG.isEnabledFor(Priority.WARN)) LOG.warn("Cannot access parent's DiscoveryService Service");
return;
}
try {
parentDiscovery.publish(rdv,
DiscoveryService.ADV,
lease,
lease);
} catch (IOException e) {
if (LOG.isEnabledFor(Priority.WARN)) LOG.warn("Cannot locally publish advertisement");
}
}
/**
*Description of the Class
*/
public class RdV {
/**
*Description of the Field
*/
protected String peer;
/**
*Description of the Field
*/
protected long lease;
/**
*Constructor for the RdV object
*
* @param peer Description of Parameter
*/
public RdV(String peer) {
this.peer = peer;
this.lease = 0;
}
/**
*Description of the Method
*
* @param obj Description of Parameter
* @return Description of the Returned Value
*/
public boolean equals(Object obj) {
RdV rdv = (RdV) obj;
return (rdv.peer.equals(peer));
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -