Usando o Couchbase Ruby Gem com o EventMachine

Como você deve ter notado, o novo gem rubi do couchbase foi lançado recentemente. A versão 1.2.2 é principalmente uma versão de manutenção com várias correções de bugs, mas você ainda pode experimentar um novo recurso experimental: integração com Máquina de eventos biblioteca. Este post lhe dará uma rápida introdução sobre como começar a usar o Couchbase Server com seus aplicativos baseados no modelo assíncrono EventMachine.

A integração do EventMachine só pode ser acessada (atualmente) em sistemas do tipo UNIX (como Linux, Solaris, BSD). Como usa fibras, também requer o MRI ruby versão 1.9 ou posterior.

Configure sua sandbox

A primeira etapa é instalar a biblioteca libcouchbase, que lida com todos os detalhes de baixo nível do protocolo do Couchbase. Você pode seguir o guia guia de instalação na página oficial. Aqui, apenas replicarei as etapas necessárias para uma máquina GNU/Linux típica (estou usando o Debian instável):

  1. Instalar a chave PGP do repositório:

    $ wget -O- http://packages.couchbase.com/ubuntu/couchbase.key | sudo apt-key add -

  2. Configurar a fonte do repositório. Aqui estou usando o link para o Ubuntu 12.04, mas, em geral, isso não importa, pois usaremos o plug-in EventMachine, que foi incorporado à própria gema. Os pacotes estão em diferentes repositórios de pacotes criados usando a mesma base de código; a única diferença é a versão das bibliotecas IO (libevent, libev) incluído na versão da distribuição.

    $ sudo wget -O/etc/apt/sources.list.d/couchbase.list http://packages.couchbase.com/ubuntu/couchbase-ubuntu1204.list

  3. Instale os cabeçalhos da libcouchbase, a biblioteca principal e os símbolos de depuração. Novamente, talvez você queira instalar ferramentas de linha de comando ou um dos back-ends de E/S, mas isso não é necessário para a tarefa em questão.

    $ sudo apt-get update
    $ sudo sudo apt-get install libcouchbase-dev libcouchbase2-core libcouchbase-dbg
     

    É isso aí. 

    Agora você precisa instalar Servidor CouchbaseSiga as instruções do site oficial. Após a instalação, você terá o console do administrador em execução em http://localhost:8091 e também a API REST acessível na mesma porta. Siga as etapas de configuração inicial e, por fim, você alocará um bucket com o nome "default".

  4. Por fim, você precisa instalar a própria gem. É tão fácil quanto digitar isso no terminal:

    $ gem install couchbase
    Criação de extensões nativas. Isso pode demorar um pouco...
    Instalação bem-sucedida do couchbase-1.2.2
    1 gema instalada
    Instalando a documentação do ri para couchbase-1.2.2...
    Instalando a documentação RDoc para couchbase-1.2.2...

Criação do aplicativo

Para demonstrar a integração, vamos criar um aplicativo de bate-papo simples usando o EventMachine e adicionar o registro de todos os eventos em um bucket do Couchbase. É extremamente fácil criar um aplicativo assíncrono com o EventMachine e, para provar isso, colocarei o código-fonte completo nesta publicação (também encontrado em exemplos/chat-em dos códigos-fonte da gem).

class ChatServer < EM::Connection

  @@clientes = []

  def post_init
    @username = nil
    send_data("*** Qual é o seu nome?n")
  final

  def receive_data(data)
    se @nomedeusuário
      broadcast(data.strip, @username)
    mais
      name = data.gsub(/s+|[[]]/, '').strip[0..20]
      if name.empty?
        send_data("*** Qual é o seu nome?n")
      mais
        @username = nome
        @@clients.push(self)
        broadcast("#{@username} has joined")
        send_data("*** Hi, #{@username}!n")
      final
    final
  final

  def unbind
    @@clients.delete(self)
    broadcast("#{@username} has left") if @username
  final

  def broadcast(message, author = nil)
    prefixo = autor ? "" : "***"
    @@clients.each do |client|
      a menos que cliente == self
        client.send_data("#{prefix} #{message}n")
      final
    final
  final

final

EventMachine.run do
  # pressione Control + C para parar
  Signal.trap("INT") { EventMachine.stop }
  Signal.trap("TERM") { EventMachine.stop }

  EventMachine.start_server("0.0.0.0", 9999, ChatServer)
final

Esse é um servidor EventMachine típico baseado em EM::Connection. Para aqueles que não sabem o significado desses métodos redefinidos, aqui está um trecho da seção documentação oficial:

EventMachine::Connection é uma classe que é instanciada pelo loop de processamento do EventMachine sempre que uma nova conexão é criada. (As novas conexões podem ser iniciadas localmente em um servidor remoto ou aceitas localmente de um cliente remoto). Quando um objeto Connection é instanciado, ele mistura a funcionalidade contida no módulo definido pelo usuário especificado nas chamadas para connect ou start_server. Os módulos manipuladores definidos pelo usuário podem redefinir qualquer um ou todos os métodos padrão definidos aqui, bem como adicionar código adicional arbitrário que também será misturado.

O EventMachine gerencia um objeto herdado do EventMachine::Connection (e que contém o código de usuário misturado) para cada conexão de rede que estiver ativa em um determinado momento. O loop de eventos chamará automaticamente os métodos dos objetos EventMachine::Connection sempre que ocorrerem eventos específicos nas conexões correspondentes, conforme descrito abaixo.

Essa classe nunca é instanciada pelo código do usuário e não publica um método de inicialização. Os métodos de instância de EventMachine::Connection que podem ser chamados pelo loop de eventos são: #post_init, #connection_completed, #receive_data, #unbind, #ssl_verify_peer (se TLS for usado), #ssl_handshake_completed

Todos os outros métodos de instância definidos aqui são chamados apenas pelo código do usuário.

O protocolo é muito simples e orientado por linhas. Para cada conexão, o EventMachine criará uma instância do ChatServer, que primeiro perguntará o nome do novo participante e, em seguida, transmitirá todas as suas mensagens para o grupo. Você pode usar sua ferramenta favorita que permita a comunicação por meio de um protocolo de texto arbitrário, como telnet, por exemplo, ou nc. Aqui está um exemplo de sessão entre pontos de extremidade.

~ $ telnet localhost 9999 ??? ~ $ nc localhost 9999
Tentando 127.0.0.1... ???? *** Qual é o seu nome?
Conectado ao localhost. alice
O caractere de escape é '^]'. *** Olá, Alice!
*** Qual é o seu nome? ??? *** O Bob juntou-se a nós
bob ??? olá a todos
*** Olá, Bob! Olá, Bob! Como você está?
Olá a todos ??? ^C
Olá, Bob! Como você está? ??? ~ $
*** A Alice foi embora?
^]                                  ???
telnet> Conexão fechada. ???
~ $                                 ???

Agora é hora de adicionar um pouco do Couchbase. Imagine que eu gostaria de manter todas as mensagens em um banco de dados distribuído da forma mais eficiente possível. O Couchbase é a resposta :). Para isso, preciso de:

Implemente um método de registro na classe ChatServer, que deve aceitar a mensagem e um autor opcional (para eventos do sistema, ele será nulo):

def log(message, author = nil)
  Couchbase.bucket.incr("log:key", :initial => 1) do |res|
    entrada = {
      'time' => Time.now.utc,
      'author' => author || "[system]",
      'message' => mensagem
    }
    Couchbase.bucket.set("log:#{res.value}", entry)
  final
final

Em seguida, adiciono uma chamada para log(message, author) no método de transmissão logo antes de iterar todos os clientes conectados. E envolvo EventMachine.start_server com o retorno de chamada Couchbase::Bucket#on_connect, para executar o servidor logo após o cliente ter sido conectado. A execução do loop resultante terá a seguinte aparência:

EventMachine.run do
  # pressione Control + C para parar
  Signal.trap("INT") { EventMachine.stop }
  Signal.trap("TERM") { EventMachine.stop }

  Couchbase.connection_options = {:async => true, :engine => :eventmachine}
  Couchbase.bucket.on_connect do |res|
    if res.success?
      EventMachine.start_server("0.0.0.0", 9999, ChatServer)
    mais
      coloca "Não é possível se conectar ao servidor Couchbase: #{res.error}"
    final
  final
final

Por enquanto é isso! No futuro, podemos expandir esse exemplo para usar técnicas mais modernas, como em-sincronia e talvez websockets. Acompanhe este blog para obter atualizações.

Pontos de bônus

Apenas registrar pode não ser tão interessante, mas com o Couchbase Server você pode realizar análises simples com consultas de visualização usando a maravilha do Map-Reduce incremental do Couchbase. Por exemplo, aqui está a função Map para obter todas as entradas em ordem cronológica.

function (doc, meta) {
  Se (doc.message) {
    Se (doc.author == "[system]" && doc.time) {
      emit(new Date(doc.time), "*** " + doc.message);
    } else {
      emit(new Date(doc.time), " " + doc.message);
    }
  }
}

E a saída JSON.

{"total_rows":6, "rows":[
  {"id": "log:1″, "key": "2013-02-11T19:08:05.000Z", "value": "*** alice has joined"},
  {"id": "log:2″, "key": "2013-02-11T19:08:18.000Z", "value": "*** bob has joined"},
  {“id”:”log:3″,”key”:”2013-02-11T19:08:38.000Z”,”value”:” hi everyone”},
  {"id": "log:4″, "key": "2013-02-11T19:08:48.000Z", "value":" hello, bob! how are you?"},
  {"id": "log:5″, "key": "2013-02-11T19:08:58.000Z", "value": "*** alice has left"},
  {"id": "log:6″, "key": "2013-02-11T19:09:01.000Z", "value": "*** bob has left"}
]}

Ok, isso é realmente tudo por enquanto. Aproveite esse novo recurso experimental. Ele terá suporte total em uma versão futura. Se você tiver algum problema, registre um problema na seção Rastreador de problemas do projeto RCBC. Correções e contribuições também são sempre bem-vindas e o código-fonte é aberto sob a licença Apache 2.0. Você encontrará o fontes no github.

Compartilhe este artigo
Receba atualizações do blog do Couchbase em sua caixa de entrada
Esse campo é obrigatório.

Autor

Postado por Sergey Avseyev, engenheiro de SDK, Couchbase

Sergey Avseyev é engenheiro de SDK na Couchbase. Sergey Avseyev é responsável pelo desenvolvimento do conector Kafka e da biblioteca subjacente, que implementa o DCP, o protocolo de replicação do Couchbase. Também mantém o PHP SDK para o Couchbase.

Deixe um comentário

Pronto para começar a usar o Couchbase Capella?

Iniciar a construção

Confira nosso portal do desenvolvedor para explorar o NoSQL, procurar recursos e começar a usar os tutoriais.

Use o Capella gratuitamente

Comece a trabalhar com o Couchbase em apenas alguns cliques. O Capella DBaaS é a maneira mais fácil e rápida de começar.

Entre em contato

Deseja saber mais sobre as ofertas do Couchbase? Deixe-nos ajudar.