PPD - Trabalho Borg

De Aulas

Links relacionados: Programação Paralela e Distribuída

Descrição

Utilizando o sistema abaixo (Borg), desenvolver um novo problema a ser resolvido de forma distribuída, implementando-o em 'Borg.java e acrescente a nova funcionalidade em Borgd.java.

Borg

Borg (apresentado a baixo) é um sistema simples em java, a titulo de aprendizado, para calcular o fatorial de um número. O sistema divide o problema em subproblemas e os distribui em outras maquinas. Cada máquina resolve parte do problema e devolve ao servidor. O sistema é dividido em 3 classes:

Borg.java

Aplicacao que divide o problema em partes, cria quantos processos forem possíveis, conforme o numero de servidores disponíveis.

Na definição dos servidores e portas para conexões podem existir dois servidores em uma mesma maquina. Nesse caso, é necessário especificar portas diferentes para cada um deles.

Neste exercício é apresentado um exemplo de criação de três processos para três servidores. Observa-se que os servidores precisam estar rodando nas máquinas especificadas caso não seja localhost.

 1/**
 2 * Copyright 2001-2050 Saulo Popov Zambiasi. All rights reserved. Last modified:
 3 * 2013/05/21
 4 * 
 5 * Borg
 6 * 
 7 * Divide tarefa em partes, criando um processo para cada servidore requisitado.
 8 * 
 9 * Neste exercicio eh apresentado um exemplo de criacao de tres processos para
10 * três servidores. Quando houver dois servidores rodando na mesma maquina, eh
11 * necessario configurar portas diferentes para cada servidor.
12 *  
13 * Exemplo de servidores e portas:
14 * 
15 * String[] server = { "localhost", "192.168.1.1", "192.168.1.2" }
16 * 
17 * int[] port = { 4400, 4401 , 4400 }
18 */
19
20import java.math.BigDecimal;
21
22public class Borg {
23	static public void main(String[] arguments) {
24		String[] server = { "localhost", "localhost", "localhost" };
25		int[] port = { 4400, 4401, 4402 };
26		int number = 0;
27
28		// Pega o numero passado como parametro para o calculo do fatorial
29		if (arguments.length == 1) {
30			number = Integer.parseInt(arguments[0]);
31		} else {
32			System.out.println("Use: java Borg number");
33			return;
34		}
35		// Divide o numero em partes, cada parte para cada processo
36		int size = (int) (number / server.length);
37		int counter = 1;
38
39		// Criacao dos processos para controlar a comunicacao com os daemons
40		BorgProcess[] ap = new BorgProcess[server.length];
41		for (int i = 0; i < server.length; i++) {
42			try {
43				int start = counter;
44				int end = counter + size;
45				if (end > number)
46					end = number;
47				counter = end + 1;
48				String message = "fatorial " + start + " " + end;
49				// Cria o processo e envia a mensagem para o mesmo
50				ap[i] = new BorgProcess(server[i], port[i], message);
51			} catch (Exception e) {
52				System.out.println("ERRO: " + e.toString());
53			}
54		}
55
56		// Espera o retorno de cada processo e multiplica os resultados.
57		BigDecimal result = new BigDecimal("1");
58		boolean terminou = false;
59		while (!terminou) {
60			terminou = true;
61			for (int i = 0; i < server.length; i++) {
62				if (!ap[i].finished()) {
63					terminou = false;
64				} else if (ap[i].hasResponse()) {
65					result = result
66					.multiply(new BigDecimal(ap[i].getResponse()));
67				}
68			}
69		}
70		// Imprime o resultado na tela.
71		System.out.println("Factorial " + number + "! = " + result);
72	}
73}

BorgProcess.java

Cada um dos processos criados por Borg.java é uma thread e faz uma conexão especifica com cada um servidor em funcionamento.

 1/**
 2 * Copyright 2001-2050 Saulo Popov Zambiasi. All rights reserved.
 3 * Last modified: 2013/03/21
 4 * 
 5 * Borg Process:
 6 * 
 7 * Classe responsavel pela comunicacao de cada processo com um servidor.
 8 * Envia uma mensagem e espera seu retorno.
 9 */
10
11import java.io.*;
12import java.net.*;
13
14public class BorgProcess implements Runnable {
15	private String server; // IP ou nome do servidor
16	private String message; // Mensagem
17	private String response; // Mensagem recebida;
18	private int port; // Porta da conexao
19	private boolean done; // Trabalho terminado
20	private Thread runner;
21
22	BorgProcess(String server, int port, String message) {
23		this.message = message;
24		this.response = null;
25		this.server = server;
26		this.port = 4400;
27		this.done = false;
28		if (port != 0) {
29			this.port = port;
30		}
31		if (runner == null) {
32			runner = new Thread(this);
33			runner.start();
34		}
35	}
36
37	public void run() {
38		try {
39			// Conexao com o daemon
40			Socket conexao = new Socket(server, port);
41			conexao.setSoTimeout(20000);
42
43			// Envia a mensagem para o servidor
44			System.out.println("borg://" + server + ":" + port + "/send \""
45					+ message + "\"");
46			BufferedOutputStream bos = new BufferedOutputStream(
47					conexao.getOutputStream());
48			PrintWriter os = new PrintWriter(bos, false);
49			os.println(message);
50			os.flush();
51			// recebe o resultado do daemon em forma de uma mensagem
52			BufferedReader in = new BufferedReader(new InputStreamReader(
53					conexao.getInputStream()));
54			response = in.readLine();
55			System.out.println("borg://" + server + ":" + port + "/recv \""
56					+ response + "\"");
57			conexao.close();
58		} catch (IOException e) {
59			System.out.println("Erro: " + e.getMessage());
60		}
61		done = true;
62	}
63
64	String getResponse() {
65		String out = response;
66		response = null;
67		return out;
68	}
69
70	boolean hasResponse() {
71		return response != null;
72	}
73
74	boolean finished() {
75		return done;
76	}
77}

BorgServer.java

Servidor responsável por executar uma tarefa especifica.

  1/**
  2 * Copyright 2001-2050 Saulo Popov Zambiasi. All rights reserved.
  3 * Last modified: 2013/05/21
  4 * 
  5 * Borg Server: Executa as mensagens recebidas e retorna o resultado
  6 */
  7
  8import java.io.*;
  9import java.math.BigDecimal;
 10import java.net.*;
 11import java.util.*;
 12
 13public class BorgServer extends Thread {
 14	private ServerSocket sock; // Socket do servidor
 15
 16	// Construtor que inicializa a classe como thread
 17	public BorgServer(int port) {
 18		super();
 19		int serverPort = 4400;
 20		if (port != 0)
 21			serverPort = port;
 22		try {
 23			sock = new ServerSocket(serverPort);
 24			System.out.println("Borg Server running...");
 25		} catch (IOException e) {
 26			System.out.println("Erro: " + e.getMessage());
 27			System.exit(1);
 28		}
 29		start();
 30	}
 31
 32	// Mantem o servidor em execucao
 33	public void run() {
 34		while (true) {
 35			// Fica esperando o recebimento de mensagens
 36			if (sock == null) {
 37				return;
 38			}
 39			try {
 40				Socket conn = sock.accept();
 41				// Recebendo mensagem
 42				BufferedReader in = new BufferedReader(new InputStreamReader(
 43						conn.getInputStream()));
 44				String message = in.readLine();
 45				System.out.println("borg://" + conn.getInetAddress() + ":"
 46						+ conn.getPort() + "/recv \"" + message + "\"");
 47				// executando a mensagem
 48				message = execute(message);
 49				// Enviando a resposta
 50				BufferedOutputStream bos = new BufferedOutputStream(
 51						conn.getOutputStream());
 52				PrintWriter os = new PrintWriter(bos, false);
 53				System.out.println("borg::/" + conn.getInetAddress() + ":"
 54						+ conn.getPort() + "/send \"" + message + "\"");
 55				os.println(message);
 56				os.flush();
 57				os.close();
 58				conn.close();
 59			} catch (IOException e) {
 60				System.out.println("Erro: " + e.getMessage());
 61				System.exit(1);
 62			}
 63		}
 64	}
 65
 66	String execute(String msg) {
 67		String result = "null";
 68		StringTokenizer split = new StringTokenizer(msg, " ");
 69		// Verifica o comando, 1a. palavra da mensagem
 70		String command = split.nextToken();
 71		// Executa o comando de fatorial
 72		switch (command) {
 73		case "fatorial":
 74			int a = Integer.parseInt(split.nextToken());
 75			int b = Integer.parseInt(split.nextToken());
 76			// long c = 1;
 77			BigDecimal c = new BigDecimal("1");
 78			for (int i = a; i <= b; i++) {
 79				c = c.multiply(new BigDecimal(Integer.toString(i)));
 80			}
 81			result = c.toString();
 82			break;
 83		case "somatorio": // Outro exemplo
 84			double total = 0;
 85			for (int i = 0; i < split.countTokens() - 1; i++) {
 86				total += Double.parseDouble(split.nextToken());
 87			}
 88			result = Double.toString(total);
 89			break;
 90		}
 91		return result;
 92	}
 93
 94	// Programa principal
 95	public static void main(String[] arguments) {
 96		// Configura a porta, caso passada por parametro.
 97		int port = 0;
 98		if (arguments.length == 1) {
 99			port = Integer.parseInt(arguments[0]);
100		} else if (arguments.length > 1) {
101			System.out.println("Use: java Borgd port");
102			return;
103		}
104		new BorgServer(port);
105	}
106}