/** * Copyright (C) 2010-2013 Eugen Feller, INRIA <eugen.feller@inria.fr> * * This file is part of Snooze, a scalable, autonomic, and * energy-aware virtual machine (VM) management framework. * * This program 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. * * This program 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses>. */ package org.inria.myriads.snoozenode.heartbeat.sender; import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.MulticastSocket; import org.inria.myriads.snoozecommon.communication.NetworkAddress; import org.inria.myriads.snoozecommon.guard.Guard; import org.inria.myriads.snoozenode.heartbeat.message.HeartbeatMessage; import org.inria.myriads.snoozenode.util.SerializationUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Heartbeat message sender. * * @author Eugen Feller */ public final class HeartbeatMulticastSender implements Runnable { /** Define the logger. */ private static final Logger log_ = LoggerFactory.getLogger(HeartbeatMulticastSender.class); /** Heartbeat message. */ private HeartbeatMessage hearbeatMessage_; /** Heartbeat address. */ private NetworkAddress heartbeatAddress_; /** Datagram socket. */ //private DatagramSocket socket_; private MulticastSocket socket_; /** Lock object. */ private Object lockObject_; /** Heartbeat interval. */ private int heartbeatInterval_; /** Terminated. */ private boolean isTerminated_; /** * Constructor. * * @param heartbeatAddress The heartbeat address * @param heartbeatInterval The heartbeat interval * @param hearbeatMessage The heartbeat message * @throws IOException Exception */ public HeartbeatMulticastSender(NetworkAddress heartbeatAddress, int heartbeatInterval, HeartbeatMessage hearbeatMessage) throws IOException { Guard.check(heartbeatAddress, heartbeatInterval, hearbeatMessage); log_.debug(String.format("Starting multicast heartbeat sender on the group %s with port %d", heartbeatAddress.getAddress(), heartbeatAddress.getPort())); heartbeatAddress_ = heartbeatAddress; heartbeatInterval_ = heartbeatInterval; hearbeatMessage_ = hearbeatMessage; //socket_ = new DatagramSocket(); socket_ = new MulticastSocket(); //socket_.setNetworkInterface(NetworkInterface.getByName("eth1")); lockObject_ = new Object(); log_.debug("sending on interface : " + socket_.getNetworkInterface().getDisplayName()); } /** * Run method. */ public void run() { try { while (!isTerminated_) { log_.debug(String.format("Sending heartbeat message to: %s:%s", heartbeatAddress_.getAddress(), heartbeatAddress_.getPort())); send(SerializationUtils.serializeObject(hearbeatMessage_)); synchronized (lockObject_) { lockObject_.wait(heartbeatInterval_); } } } catch (IOException exception) { log_.error(String.format("I/O exception during sending: %s", exception.getMessage())); } catch (InterruptedException exception) { log_.error("Heartbeat multicast sender was interrupted", exception); } finally { close(); } log_.debug("Heartbeat multicast sender is stopped!"); } /** * Send a multicast message. * * @param message The message in bytes * @throws IOException * @throws InterruptedException */ private void send(byte[] message) throws IOException, InterruptedException { Guard.check(message); InetAddress address = InetAddress.getByName(heartbeatAddress_.getAddress()); DatagramPacket outPacket = new DatagramPacket(message, message.length, address, heartbeatAddress_.getPort()); socket_.send(outPacket); } /** * Close socket. */ private void close() { if (socket_ != null) { socket_.close(); } } /** * Terminates the thread. */ public synchronized void terminate() { log_.debug("Terminating the heartbeat multicast sender"); synchronized (lockObject_) { isTerminated_ = true; lockObject_.notify(); } } }