Lab5 Leonardo Bruno

aluno: Nome do Aluno
ano/sem: 2008/2o.
data do laboratório (num. da semana) : 06/08/2008 (2)

Introdução

Neste laboratório iremos iniciar o desenvolvimento de uma aplicação cliente servidor em Ruby. Treinaremos os concetios de Threads, IO e o padrão Decorator. A aplicação será um bolão virtual, onde os apostadores poderão dar palpites e o servidor irá reunir e tratar todas as informações dos apostadores.

Desenvolvimento

Melhoria nos Decorators de Thread Safety

Criamos um decorator para decorar métodos da classe Match e o chamamos de MatchThreadSafeDecorator:

class MatchThreadSafeDecorator < Decorator
    include MonitorMixin
 
      def make_bet(score, user)
        synchronize do
        @decorated.make_bet(score, user)
        end
      end
 
      def finalize(final_score)
          synchronize do
            @final_score = final_score.to_score
          end
      end
  end
end

Criamos uma classe MatchListThreadSafeDecorator de forma a permitir que o método add construa Matchs decorados:

class MatchListThreadSafeDecorator < Decorator
    include MonitorMixin
 
    def initialize(decorated)
      old_match_decorator = decorated.item_decorator
      decorated.item_decorator = lambda do |match|
        MatchLoggerDecorator.new( old_match_decorator.call(match) )
      end
      super
    end
 
    def add(name, end_time)
      synchronize do
      match = @decorated.add(name, end_time)
      $logger.info "Match '#{name}' was added successfully."
      match
      end
    end
end

Melhoria nos Decorators de Persistência

Criamos um decorador para a classe Match, MatchPersistanceDecorator:

class MatchPersistanceDecorator < Decorator
 
       def initialize(obj , ref_lista)
           @lista_jogos=ref_lista
           super(obj)
       end
 
       def make_bet(score, user)
 
           match=@decorated.make_bet(score, user)
           @lista_jogos.save
           return match
 
       end
 
       def finalize(final_score)
 
           o=@final_score = final_score.to_score
           @lista_jogos.save
           return o
 
       end
 
  end

Analogamente, criamos a classe MatchListPersistanceDecorator para fazer com que o método add pudesse criar jogos decorados com MatchPersistanceDecorator:

class MatchListPersistanceDecorator < ListPersistanceDecorator
 
    def initialize(obj,filename)
        old_match_decorator = obj.item_decorator
        obj.item_decorator = lambda do |match|
        MatchPersistanceDecorator.new( old_match_decorator.call(match), self )
        end
        super(obj,filename)
    end
 
    def add(nome, fim)
        obj = @decorated.add(nome, fim)
        save
        obj
    end
 
  end

Criação de Builders para UserList e MatchList com as decorações

Para treinar o uso do padrão builder, criamos a classe MatchListBuilder que facilita a construção da matchlist decorado:

class MatchListBuilder
 
  def initialize
      @match_list=MatchList.new
  end
 
  def match_list
      @match_list.load_list if @added_persistance
      @added_persistance=nil
      @match_list
  end
 
  def add_persistance
      @match_list=MatchListPersistanceDecorator.new(@match_list,"matchList.yml")
      @added_persistance=true
  end
 
  def add_thread_safety
      @match_list=MatchListThreadSafeDecorator.new(@match_list)
  end
 
  def add_logging
      @match_list=MatchListLoggerDecorator.new(@match_list)
  end
 
  def add_all
      add_persistance
      add_logging
      add_thread_safety
      @added_persistance=true
  end
 
end

De modo análogo, criamos a classe UserListBuilder:

class UserListBuilder
  def initialize
      @user_list=UserList.new()
      @added_persistance=false
  end
 
  def user_list
      @user_list.load_list if @added_persistance
      @user_list
  end
 
  def add_persistance
      @user_list=ListPersistanceDecorator.new(@user_list,"userList.yml")
      @added_persistance=true
  end
 
  def add_logging
      @user_list=UserListLoggerDecorator.new(@user_list)
  end
 
  def add_thread_safety
      @user_list=ListThreadSafeDecorator.new(@user_list)
  end
 
  def add_all
      add_persistance
      add_logging
      add_thread_safety 
      @added_persistance=true
  end
end

Criação de um método main que interprete um protocolo de entrada e saída de dados do backend

Utilizando a biblioteca yaml para formatar dos dados de entrada e saída, que consistem na execução de pedidos fornecidos na entrada. A aplicação é capaz de atender ao pedido da criação e autenticação de usuários. Assim como listar partidas atuais e encerradas, listar informações de apostas, fazer apostas e desconectar. Criou-se a classe RequestReader para interpretar o yaml de entrada e tratá-lo conforme a solicitação. O método main recebe como parâmetro os ios de entrada e saída, utilizando os builders na construção do MatchList e do UserList decorados.

Criação do servidor multithread

O servidor multi thread possibilitará conexões cimultâneas, via rede, onde cada conexão corresponde a um thread especifico:

server = TCPServer.new(4344)  # 4344 é a porta de conexão de rede usada
 
    while ( io_socket = server.accept ) #aguarda até que conexão seja recebida, retornando um TCPSocket com a conexão.
     # dispare uma nova thread e utilize io_socket para efetuar a entrada e saída do método main, de dentro desta thread
     Thread.new do
     #io_socket deve ser utilizado tanto para saída quanto para entrada, portanto é passado como parâmetro in e parâmetro out de main.
       main(io_socket,io_socket)
       io_socket.close
    end
    end

Conclusão

Assim, após este laboratório podemos ter uma experiência em desenvolvimento de uma aplicação cliente servidor em Ruby. Treinamos os concetios de Threads, IO e o padrão Decorator. Embora grande parte da aplicação já estivesse encaminhada, foi necessário um montante significativo de tempo para a compeensão do código, o que foi muito instrutivo.

Add a New Comment
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License