/******************************************************************************* * Copyright (c) 2007, 2016 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.core; import java.io.IOException; import java.util.Map; import org.eclipse.tcf.internal.core.RemotePeer; import org.eclipse.tcf.internal.services.local.LocatorService; import org.eclipse.tcf.protocol.IPeer; import org.eclipse.tcf.protocol.JSON; import org.eclipse.tcf.protocol.Protocol; import org.eclipse.tcf.services.ILocator; import org.eclipse.tcf.services.ILocator.LocatorListener; /** * Abstract implementation of IPeer interface. Objects of this class are stored * in Locator service peer table. The class implements sending notification * events to Locator listeners. See TransientPeer for IPeer objects that are not * stored in the Locator table. */ public class AbstractPeer extends TransientPeer { private long last_heart_beat_time; /** * Constructs an AbstractPeer object using the given attributes, adds the * peer to the LocatorService Peer Table and sends a "peerAdded" event to * the TCF Channel * * @param attrs attributes maps with which to initialize the peer */ public AbstractPeer(Map<String, String> attrs) { super(attrs); assert Protocol.isDispatchThread(); String id = getID(); assert id != null; Map<String, IPeer> peers = LocatorService.getLocator().getPeers(); if (peers.get(id) instanceof RemotePeer) { ((RemotePeer) peers.get(id)).dispose(); } assert peers.get(id) == null; peers.put(id, this); sendPeerAddedEvent(); } /** * Removes the Peer from the Locator Service Peer table and sends a * "peerRemoved" event to the TCF Channel */ public void dispose() { assert Protocol.isDispatchThread(); String id = getID(); assert id != null; Map<String, IPeer> peers = LocatorService.getLocator().getPeers(); assert peers.get(id) == this; peers.remove(id); sendPeerRemovedEvent(); } /** * Method called whenever a channel is terminated */ void onChannelTerminated() { // A channel to this peer was terminated: // not delaying next heart beat helps client to recover much faster. last_heart_beat_time = 0; } /** * Updates Peer properties using the given attributes parameters * @param attrs - attributes map with which to update the peer */ public void updateAttributes(Map<String, String> attrs) { long time = System.currentTimeMillis(); if (!attrs.equals(ro_attrs)) { assert attrs.get(ATTR_ID).equals(rw_attrs.get(ATTR_ID)); rw_attrs.clear(); rw_attrs.putAll(attrs); for (LocatorListener l : LocatorService.getListeners()) { try { l.peerChanged(this); } catch (Throwable x) { Protocol.log("Unhandled exception in Locator listener", x); } } try { Object[] args = { rw_attrs }; Protocol.sendEvent(ILocator.NAME, "peerChanged", JSON.toJSONSequence(args)); } catch (IOException x) { Protocol.log("Locator: failed to send 'peerChanged' event", x); } last_heart_beat_time = time; } else if (last_heart_beat_time + ILocator.DATA_RETENTION_PERIOD / 4 < time) { for (LocatorListener l : LocatorService.getListeners()) { try { l.peerHeartBeat(attrs.get(ATTR_ID)); } catch (Throwable x) { Protocol.log("Unhandled exception in Locator listener", x); } } try { Object[] args = { rw_attrs.get(ATTR_ID) }; Protocol.sendEvent(ILocator.NAME, "peerHeartBeat", JSON.toJSONSequence(args)); } catch (IOException x) { Protocol.log("Locator: failed to send 'peerHeartBeat' event", x); } last_heart_beat_time = time; } } /** * Sends a "peerAdded" event to the TCF Channel */ private void sendPeerAddedEvent() { for (LocatorListener l : LocatorService.getListeners()) { try { l.peerAdded(this); } catch (Throwable x) { Protocol.log("Unhandled exception in Locator listener", x); } } try { Object[] args = { rw_attrs }; Protocol.sendEvent(ILocator.NAME, "peerAdded", JSON.toJSONSequence(args)); } catch (IOException x) { Protocol.log("Locator: failed to send 'peerAdded' event", x); } last_heart_beat_time = System.currentTimeMillis(); } /** * Sends a "PeerRemoved" event to the TCF Channel */ private void sendPeerRemovedEvent() { for (LocatorListener l : LocatorService.getListeners()) { try { l.peerRemoved(rw_attrs.get(ATTR_ID)); } catch (Throwable x) { Protocol.log("Unhandled exception in Locator listener", x); } } try { Object[] args = { rw_attrs.get(ATTR_ID) }; Protocol.sendEvent(ILocator.NAME, "peerRemoved", JSON.toJSONSequence(args)); } catch (IOException x) { Protocol.log("Locator: failed to send 'peerRemoved' event", x); } } }