All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.eduworks.lang.threading.EwDistributedThreading Maven / Gradle / Ivy

package com.eduworks.lang.threading;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MulticastSocket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.eduworks.EwVersion;
import com.eduworks.mapreduce.MapReduceClient;
import com.eduworks.mapreduce.MapReduceListener;
import com.eduworks.mapreduce.MapReduceServer;
import com.eduworks.util.Tuple;

public class EwDistributedThreading
{
	static boolean debug = true;
	static DatagramSocket socket = null;
	static MulticastSocket mcsocket = null;
	static Logger log;
	static
	{
		log = Logger.getLogger(EwDistributedThreading.class);
		try
		{
			socket = new DatagramSocket(null);
			socket.bind(new InetSocketAddress(Inet4Address.getByName("0.0.0.0"), 4445));
			log.info("Bound " + Inet4Address.getByName("0.0.0.0") + " Datagram Socket to 4445.");
		}
		catch (SocketException e1)
		{
			e1.printStackTrace();
		}
		catch (UnknownHostException e)
		{
			e.printStackTrace();
		}
		try
		{
			log.info("Attempting to bind Multicast Socket to 4446.");
			mcsocket = new MulticastSocket(4446);
			InetAddress group = InetAddress.getByName("224.0.121.0");
			mcsocket.joinGroup(group);
			log.info("Success.");
		}
		catch (IOException e)
		{
			log.info("Failed.");
			e.printStackTrace();
		}
		Thread t = new Thread(new Runnable()
		{

			@Override
			public void run()
			{
				DatagramPacket packet;
				try
				{
					mcsocket.setBroadcast(true);
					mcsocket.setSoTimeout(90000);
				}
				catch (SocketException e1)
				{
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}

				for (int i = 0;; i++)
				{
					byte[] buf = new byte[256];
					packet = new DatagramPacket(buf, buf.length);
					try
					{
						mcsocket.receive(packet);
						String received = new String(packet.getData(), Charset.defaultCharset());
						receiveBroadcast(packet.getAddress(), received);
					}
					catch (SocketTimeoutException ex)
					{

					}
					catch (Exception e)
					{
						e.printStackTrace();
					}
					heartbeat();
				}
			}
		});
		t.start();
	}

	public static class Peer
	{
		long lastHeartbeat;
		long threadsInUse;
		String version;
		String ip;
		public String name;
		public short port;
	}

	static Map peers = new HashMap();

	protected static void receiveBroadcast(InetAddress inetAddress, String received)
	{
		String[] split = received.split("\t");
		String ip = inetAddress.getHostAddress();
		String receivedVersion = split[0];
		String receivedLoad = split[1];
		String receivedName = split[2];
		String receivedPort = split[3];

		String key = ip + receivedName + receivedPort;

		// log.debug("Received broadcast from " + ip + ": " + received);
		if (!peers.containsKey(key))
			peers.put(key, new Peer());
		Peer p = peers.get(key);
		p.ip = ip;
		p.lastHeartbeat = System.currentTimeMillis();
		p.version = receivedVersion;
		p.threadsInUse = Long.parseLong(receivedLoad);
		p.name = receivedName;
		p.port = Short.parseShort(receivedPort);
		heartbeat();
	}

	public static void sendBroadcast(String buf) throws IOException
	{
		sendBroadcast(buf.getBytes(Charset.defaultCharset()));
	}

	public static void sendBroadcast(byte[] buf) throws IOException
	{
		InetAddress group;
		group = InetAddress.getByName("224.0.121.0");
		DatagramPacket packet;
		packet = new DatagramPacket(buf, buf.length, group, 4446);
		socket.send(packet);
	}

	static long lastHeartbeat = 0;

	public static void heartbeat()
	{
		if (System.currentTimeMillis() - lastHeartbeat < 5000)
			return;
		// log.debug("Heartbeating.");
		lastHeartbeat = System.currentTimeMillis();
		try
		{
			
			String versionNumber = EwVersion.getVersion();
			String tasks = Long.toString(EwThreading.getTaskCount());
			if (mrs == null)
				mrs = new ArrayList();
			for (MapReduceServer mr : mrs)
			{
				// log.debug("Heartbeating. Sending broadcast packet for " +
				// mr.name);
				sendBroadcast(versionNumber.trim() + "\t" + tasks + "\t" + mr.name + "\t" + mr.port + "\t");
			}
		}
		catch (IOException e)
		{
			System.out.println(e.getMessage());
		}
	}

	public static MapReduceClient acquireWorkforce(String name) throws Exception
	{
		List candidates = new ArrayList();
		for (Peer p : peers.values())
			if (System.currentTimeMillis() - p.lastHeartbeat < 120000)
				if (name.equals(p.name))
					if (p.threadsInUse < 5)
						candidates.add(p);
		List> hosts = new ArrayList>();
		for (Peer p : candidates)
			hosts.add(new Tuple(p.ip, p.port));
		if (hosts.size() == 0)
			throw new Exception("No peers available.");
		MapReduceClient mrc = new MapReduceClient(name, hosts);
		return mrc;
	}

	static List mrs = new ArrayList();

	public static void subscribe(String name, short port, MapReduceListener mapReduceListener)
	{
		if (mrs == null)
			mrs = new ArrayList();
		MapReduceServer mrm;
		try
		{
			log.debug("Subscribing new map reduce listener " + name);
			mrm = new MapReduceServer(name, port, mapReduceListener);
			mrs.add(mrm);
		}
		catch (RemoteException e)
		{
			e.printStackTrace();
		}
		catch (AlreadyBoundException e)
		{
			e.printStackTrace();
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy