Hoje estamos lançando a versão Beta 2 do Couchbase .NET SDK 2.0. Essa é uma atualização empolgante em nosso compromisso contínuo com a plataforma .NET e com a comunidade .NET. Conseguimos até mesmo incluir alguns novos recursos antes do lançamento da versão GA em resposta à demanda dos clientes. Tenho o prazer de anunciar a inclusão de métodos em massa e uma prévia das visualizações assíncronas e das consultas N1QL!

O que há nesta versão?

Em termos de recursos, ele se baseia nas versões anteriores (DP1, DP2 e Beta) e acrescenta o seguinte:

  • Métodos em massa: Upsert e Get
  • Exibições assíncronas
  • Consultas assíncronas do N1QL (Experimental - o N1QL ainda é DP3)
  • Tipos de dados comuns - digitação consistente de valores entre SDKs
  • API de gerenciamento - para gerenciar clusters, buckets e visualizações

Métodos em massa: Upsert e Get

Os métodos em massa permitem que o aplicativo envie um conjunto de chaves em uma única solicitação e aguarde os resultados. Por exemplo:

usando(var cluster = novo Aglomerado())
{
    usando (var bucket = agrupamento.OpenBucket())
    {
        var itens = novo Dicionário<stringdinâmica>
        {
            {"Key1", "string"},
            {"Key2", novo {Foo = "Bar", Baz = 2}},
            {"Key3", 2},
            {"Key4", 5.8},
            {"Key5", novo[] {0x00, 0x00}}
         }
        var multiUpsert = balde.Upsert(itens);
        antes de (var item em multiUpsert)
        {
            Afirmar.IsTrue(item.Valor.Sucesso);
        }
   }
}

Acima, estamos criando um objeto Cluster e abrindo o Bucket padrão. Depois disso, criamos um dicionário com suas chaves definidas como string e seus valores definidos como um tipo dinâmico. Em seguida, adicionamos várias chaves e valores associados; observe que cada valor é um tipo diferente: uma cadeia de caracteres, um tipo anônimo, um inteiro, um decimal e, finalmente, uma matriz de bytes. Em seguida, chamamos IBucket.Upsert(...) e passamos o dicionário. Em seguida, estamos iterando pelos resultados, verificando se cada operação foi bem-sucedida.

Nos bastidores, estamos aproveitando a Task Parallel Library para disparar cada operação em paralelo. Para essa sobrecarga, são usadas as ParallelOptions padrão, mas há sobrecargas que permitem que você passe suas próprias ParallelOptions (incluindo seu próprio CancellationToken) e controle o tamanho de cada partição de chaves que será processada por iteração.

Exibições assíncronas

Embora o suporte a operações CRUD assíncronas (InsertAsync, UpsertAsync etc.) não tenha entrado no GA, as exibições assíncronas entraram. A implementação baseia-se no TAP (Task Asynchrony Pattern), que é familiar para a maioria dos desenvolvedores de .NET e oferece suporte às palavras-chave async/await introduzidas no .NET 4.0:

público assíncrono vazio QueryAsync()
{
        usando (var bucket = _cluster.OpenBucket("amostra de cerveja"))
        {
            var query = balde.
                Criar Consulta("cerveja", "brewery_beers" (cervejarias)).
                Limite(10);

            var result = aguardar balde.QueryAsync<dinâmico>(consulta);
            antes de (var row em resultado.Fileiras)
            {
                Console.WriteLine(fila);
            }
        }
}

Aqui estamos abrindo o bucket "beer-sample" de um objeto de cluster já criado e, em seguida, criando uma consulta que terá como alvo a visualização "brewery_beers" definida pelo documento de design "beer". É importante observar que estamos usando a palavra-chave await para sinalizar uma espera assíncrona e que o método de chamada tem a palavra-chave async definida; além disso, o nome do método que está executando a consulta chamada é pós-fixado com "Async": QueryAsync(consulta IViewQuery). O que está acontecendo aqui é que a solicitação de consulta será disparada de um thread ThreadPool e não do thread principal. Coisa legal.

Consultas assíncronas N1QL (experimental)

Semelhante às visualizações assíncronas, adicionamos sobrecargas para a execução de consultas N1QL de forma assíncrona usando as palavras-chave async/await:

público assíncrono vazio ConsultaN1QLAsync()
{
    usando (var bucket = _cluster.OpenBucket())
    {
         const string consulta = "SELECT * " +
                                 "FROM tutorial " +
                                 "WHERE fname = 'Ian'";

          var result = aguardar balde.QueryAsync<dinâmico>(consulta);
          antes de (var row em resultado.Fileiras)
          {
                Console.WriteLine(fila);
           }
       }
 }

Mais uma vez, adicionamos a palavra-chave "async" à assinatura do método que executa a consulta e, em seguida, usamos a palavra-chave "await" para fazer uma espera assíncrona enquanto a consulta é executada fora do thread principal e em um thread ThreadPool. Quando a chamada retorna, iteramos os resultados como qualquer outra consulta N1QL.

Tipos de dados comuns

É bastante comum que um ambiente corporativo tenha uma ou mais equipes de desenvolvedores usando mais de uma plataforma para fornecer soluções de software que satisfaçam as necessidades comerciais da organização. Por exemplo, uma camada escrita em Java que expõe os serviços principais a terceiros e outra camada escrita em .NET que consome os dados enviados pela camada Java. Em situações como essa, em que uma plataforma está gravando dados no Couchbase e outra plataforma está lendo esses dados, é importante que o tipo de dados subjacente de cada item armazenado no Couchbase seja tratado da mesma forma em ambas as plataformas e em seus respectivos SDKs.

No passado, havia alguma inconsistência na forma como os vários SDKs lidavam com a transcodificação de tipos, mas isso mudou nos SDKs 2.0. Agora, quando um SDK, como o Python, armazena um documento ou valor, quando outra plataforma ler esse valor, ele será transcodificado como o mesmo tipo. Isso é feito simplesmente tratando um subconjunto de tipos como JSON, strings, dados binários ou como um tipo "privado" para compatibilidade com versões anteriores. Essas informações de tipo são armazenadas como um "sinalizador comum" nos metadados dos documentos e usadas pelos SDKs para determinar como lidar com a transcodificação de forma consistente.

API de gerenciamento

O último recurso importante lançado no GA é uma API de gerenciamento totalmente nova para executar tarefas no nível do cluster e do bucket, como criar e remover buckets, documentos de design e visualizações, além de adicionar e remover nós de um cluster.

A API de gerenciamento pode ser dividida em dois tipos distintos de operações: as que são executadas em um Bucket e as que são executadas no Cluster. Cada uma delas é representada por seus respectivos objetos gerenciadores, que são criados pelos métodos de fábrica do objeto Cluster.

Aqui está um exemplo de adição de um nó a um cluster:

usando (var cluster = novo Aglomerado(configuração))
{
    var clusterManager = agrupamento.Gerenciador de criação("Administrador", "senha");
    var result = gerenciador de cluster.AddNode(“192.168.56.103”);
    Afirmar.IsTrue(resultado.Sucesso);
}

Primeiro, criamos um objeto Cluster, que é o mesmo objeto que usamos para abrir Buckets, passando uma configuração que informa ao Cluster onde o cluster remoto existe. Em seguida, chamamos o método de fábrica CreateManager(...), informando o nome de usuário e a senha administrativos do nosso cluster. Após a autenticação, adicionamos um novo nó ao cluster e verificamos se a solicitação foi atendida conforme o esperado.

No próximo exemplo, será executada uma tarefa administrativa em nível de compartimento: adicionar um novo documento de design e visualização a um compartimento.

usando (var cluster = novo Aglomerado(configuração))
{
    usando (var bucket = agrupamento.OpenBucket())
    {
        var manager = balde.Gerenciador de criação("Administrador", “”);
        var designDoc = Arquivo.ReadAllText(@"Dados\DesignDocs\by_field.json");
        var result = gerente.InserirDesignDocumento("by_field", designDoc);
        Afirmar.IsTrue(resultado.Sucesso);
    }
}

Aqui estamos criando um objeto Cluster, abrindo o Bucket padrão e usando um método de fábrica para criar o objeto BucketManager. Depois de termos o gerenciador, abrimos um arquivo que contém um documento de design e o View como JSON e usamos o método InsertDesignDocument(...) para adicionar o documento de design "by_field" ao Bucket. Além de inserir um documento de design, existem métodos adicionais para atualizar um documento de design existente, obter um documento de design ou todos os documentos de design e remover um documento de design.

O que mudou?

Entre o Beta e o Beta 2, ocorreram várias alterações no SDK. Na maioria das vezes, elas são aditivas ou internas e não afetarão os usuários que começaram a usar o SDK 2.0. No entanto, há algumas alterações que são de ruptura, principalmente:

Também ocorreram várias outras alterações menores, principalmente envolvendo a renomeação e/ou reordenação de parâmetros.  

  • Couchase.CouchbaseCluster foi renomeado para Couchbase.Cluster
  • O CouchbaseBucket e o MemchachedBucket foram movidos do Couchbase.Core.Buckets para o namespace principal do Couchbase.

O que não está incluído nesta versão?

Embora nos esforcemos para incluir o maior número possível de recursos em uma versão, sempre há mais recursos do que ciclos disponíveis, ao que parece, e alguns recursos não chegaram ao GA. Os mais notáveis são:

  • Leituras de réplicas: permite que o cliente leia de uma ou mais réplicas. Isso é usado principalmente para cenários de rebalanceamento quando um "Not My VBucket" pode ser encontrado.
  • Operações CRUD assíncronas usando async/await
  • Analisador JSON conectável: a capacidade de usar o serializador/deserializador JSON de sua escolha. Atualmente, o cliente conta com o Newtonsoft.JSON.
  • Per connection TCP heartbeat settings: currently this is configured at the OS level via KeepAliveTime on Windows: http://technet.microsoft.com/en-us/library/cc782936%28WS.10%29.aspx

Como obtê-lo

Os binários estão disponíveis no S3, o código-fonte está no Github e os pacotes estão disponíveis no Nuget:

  • Os binários são aqui.
  • O repositório é aqui.
  • Os pacotes NuGet são aqui.

Agradecimentos

Por ser um projeto de código aberto, o Couchbase .NET SDK depende de contribuições da comunidade, não importa quão pequenas sejam. Um agradecimento especial extra aos seguintes que enviaram solicitações pull e/ou emitiram relatórios de bugs:

  • Matt Nischan
  • Vojta Jakubec

Autor

Postado por Jeff Morris, engenheiro de software sênior, Couchbase

Jeff Morris é engenheiro de software sênior da Couchbase. Antes de ingressar na Couchbase, Jeff passou seis anos na Source Interlink como arquiteto da Web corporativa. Jeff é responsável pelo desenvolvimento dos SDKs do Couchbase e pela integração com o N1QL (linguagem de consulta).

2 Comentários

  1. Excelente trabalho!
    E quanto ao LINQ? Não é mencionado em nenhum lugar desta postagem, nem mesmo na seção O que não está nesta versão?
    Espero que não tenha sido deixado para trás...

    1. Oi Doron -

      O projeto Linq2Couchbase está vivo e ativo, mas é uma camada separada sobre o SDK. Você pode encontrá-lo aqui: https://github.com/couchbasela

      Observe que ainda não atualizei os pacotes do nuget para a versão beta2, portanto, provavelmente não funcionará até que seja atualizado; algumas alterações estruturais o quebrarão.

      Obrigado!

      Jeff

Deixar uma resposta