Hoy lanzamos la Beta 2 del SDK .NET 2.0 de Couchbase. Esta es una emocionante actualización en nuestro continuo compromiso con la plataforma .NET, y la comunidad .NET. Incluso nos las hemos arreglado para incluir algunas nuevas características antes de la versión GA en respuesta a la demanda de los clientes. Me complace anunciar la inclusión de métodos masivos y un adelanto de las vistas asíncronas y las consultas N1QL.
¿Qué contiene esta versión?
En cuanto a funciones, se basa en las versiones anteriores (DP1, DP2 y Beta) y añade las siguientes:
- Métodos masivos: Upsert y Get
- Vistas asíncronas
- Consultas asíncronas N1QL (Experimental - N1QL sigue siendo DP3)
- Tipos de datos comunes: tipificación coherente de valores entre SDK
- API de gestión: para gestionar clústeres, cubos y vistas.
Métodos masivos: Upsert y Get
Los métodos masivos permiten a la aplicación enviar un conjunto de claves en una única petición y esperar los resultados. Por ejemplo:
{
utilizando (var cubo = grupo.OpenBucket())
{
var artículos = nuevo Diccionario<cadenadinámico>
{
{"Clave1", "cadena"},
{"Llave2", nuevo {Foo = "Bar"Baz = 2}},
{"Llave3", 2},
{"Llave4", 5.8},
{"Llave5", nuevo[] {0x00, 0x00}}
}
var multiUpsert = cubo.Upsert(artículos);
foreach (var artículo en multiUpsert)
{
Afirme.IsTrue(artículo.Valor.Éxito);
}
}
}
Arriba estamos creando un objeto Cluster, y abriendo el Bucket por defecto. Después construimos un diccionario con sus claves definidas como cadenas y sus valores definidos como tipos dinámicos. A continuación, añadimos una serie de claves y valores asociados; observe que cada valor es un tipo diferente: una cadena, un tipo anónimo, un entero, un decimal y, finalmente, una matriz de bytes. A continuación llamamos a IBucket.Upsert(...) y le pasamos el diccionario. A continuación iteramos a través de los resultados comprobando si cada operación se ha realizado correctamente.
Entre bastidores estamos aprovechando la biblioteca Task Parallel Library para lanzar cada operación en paralelo. Para esta sobrecarga se utilizan las ParallelOptions por defecto, pero hay sobrecargas que te permiten pasar tus propias ParallelOptions (incluyendo tu propio CancellationToken) y controlar el tamaño de cada partición de claves que será procesada por iteración.
Vistas asíncronas
Aunque las operaciones CRUD asíncronas (InsertAsync, UpsertAsync, etc.) no se incluyeron en la versión GA, sí lo hicieron las vistas asíncronas. La implementación se basa en el patrón de asincronía de tareas (TAP) que resulta familiar a la mayoría de los desarrolladores .NET y admite las palabras clave async/await introducidas en .NET 4.0:
{
utilizando (var cubo = _cluster.OpenBucket("muestra de cerveza"))
{
var consulta = cubo.
CrearQuery("cerveza", "cerveceria_cervezas").
Límite(10);
var resultado = esperar cubo.QueryAsync<dinámico>(consulta);
foreach (var fila en resultado.Filas)
{
Consola.WriteLine(fila);
}
}
}
Aquí estamos abriendo el bucket "beer-sample" desde un objeto Cluster ya creado y luego creando una consulta que tendrá como objetivo la View "brewery_beers" que está definida por el documento de diseño "beer". Es importante notar que estamos usando la palabra clave await para señalar una espera asíncrona y que el método que llama tiene definida la palabra clave async, también el nombre del método que está ejecutando la consulta llamada está postfijado con "Async": QueryAsync
Consultas N1QL asíncronas (experimental)
De forma similar a las Vistas asíncronas, hemos añadido sobrecargas para ejecutar consultas N1QL de forma asíncrona utilizando las palabras clave async/await:
{
utilizando (var cubo = _cluster.OpenBucket())
{
const cadena consulta = "SELECT *" +
"FROM tutorial" +
"WHERE fname = 'Ian'";
var resultado = esperar cubo.QueryAsync<dinámico>(consulta);
foreach (var fila en resultado.Filas)
{
Consola.WriteLine(fila);
}
}
}
Una vez más hemos añadido la palabra clave "async" a la firma del método que ejecuta la consulta y luego hemos utilizado la palabra clave "await" para hacer una espera asíncrona mientras la consulta se ejecuta fuera del hilo principal y en un hilo ThreadPool. Una vez que la llamada regresa, iteramos a través de los resultados como cualquier otra consulta N1QL.
Tipos de datos comunes
En un entorno empresarial, es bastante habitual que uno o varios equipos de desarrolladores utilicen más de una plataforma para ofrecer soluciones de software que satisfagan las necesidades empresariales de la organización. Por ejemplo, un nivel escrito en Java que expone servicios básicos a terceros y otro nivel escrito en .NET que consume los datos enviados por el nivel Java. En situaciones como esta, en las que una plataforma escribe datos en Couchbase y otra los lee, es importante que el tipo de datos subyacente de cada elemento almacenado en Couchbase se trate de la misma forma en ambas plataformas y sus respectivos SDK.
En el pasado, ha habido cierta inconsistencia en la forma en que los distintos SDK manejaban la transcodificación de tipos, pero eso cambia en los SDK 2.0. Ahora cuando un SDK, digamos Python, almacena un documento o valor, cuando otra plataforma lee ese valor, será transcodificado como el mismo tipo. Esto se hace simplemente tratando un subconjunto de tipos como JSON, cadenas, datos binarios o como un tipo "privado" para compatibilidad con versiones anteriores. Esta información de tipo se almacena como "indicador común" en los metadatos de los documentos y los SDK la utilizan para determinar cómo gestionar la transcodificación de forma coherente.
API de gestión
La última función importante lanzada en GA es una API de gestión totalmente nueva para realizar tareas a nivel de clúster y de cubo, como crear y eliminar cubos, documentos de diseño y vistas, y añadir y eliminar nodos de un clúster.
La API de gestión puede dividirse en dos tipos distintos de operaciones: las que se realizan en un Cubo y las que se realizan en el Cluster. Cada una de ellas está representada por sus respectivos objetos gestores, que se crean mediante los métodos de fábrica del objeto Cluster.
Este es un ejemplo de cómo añadir un nodo a un Cluster:
{
var clusterManager = grupo.CreateManager("Administrador", "contraseña");
var resultado = clusterManager.AñadirNodo(“192.168.56.103”);
Afirme.IsTrue(resultado.Éxito);
}
Primero creamos un objeto Cluster, que es el mismo objeto que usamos para abrir Buckets, pasándole una configuración que le dice al Cluster donde existe el cluster remoto. Luego llamamos al método de fábrica CreateManager(...) pasándole el nombre de usuario y contraseña de administración de nuestro cluster. Una vez que nos hemos autenticado, añadimos un nuevo nodo al cluster y comprobamos que la petición ha sido atendida como se esperaba.
En el siguiente ejemplo, se realizará una tarea administrativa a nivel de Bucket: añadir un nuevo Documento de Diseño y Vista a un Bucket.
{
utilizando (var cubo = grupo.OpenBucket())
{
var gestor = cubo.CreateManager("Administrador", “”);
var diseñoDoc = Archivo.LeerTodoTexto(@"Datos\DesignDocs\by_field.json");
var resultado = director.InsertarDocumentoDeDiseño("by_field", designDoc);
Afirme.IsTrue(resultado.Éxito);
}
}
Aquí estamos creando un objeto Cluster, luego abrimos el Bucket por defecto y usamos un método factory para crear el objeto BucketManager. Una vez que tenemos el gestor, abrimos un archivo que contiene un Documento de Diseño y una Vista como JSON y usamos el método InsertDesignDocument(..) para añadir el Documento de Diseño "by_field" al Bucket. Además de insertar un documento de diseño, existen métodos adicionales para actualizar un documento de diseño existente, obtener un documento de diseño o todos los documentos de diseño y para eliminar un documento de diseño.
¿Qué ha cambiado?
Entre Beta y Beta 2, se han producido una serie de cambios en el SDK. En su mayor parte son aditivos o internos y no afectarán a los usuarios que hayan empezado a utilizar el SDK 2.0. Sin embargo, hay un par de cambios que son cambios de ruptura, sobre todo:
También se han introducido otros cambios menores, sobre todo en la denominación y reordenación de los parámetros.
- Couchase.CouchbaseCluster ha sido renombrado a Couchbase.Cluster
- CouchbaseBucket y MemchachedBucket se han movido de Couchbase.Core.Buckets al espacio de nombres principal de Couchbase.
¿Qué no incluye esta versión?
Aunque nos esforzamos por incluir tantas funciones como sea posible en una versión, parece que siempre hay más funciones que ciclos disponibles y algunas no llegaron a la versión GA. En particular:
- Lectura de réplicas: permite al cliente leer de una o más réplicas. Esto se utiliza principalmente para escenarios de reequilibrio cuando podría encontrarse un "Not My VBucket".
- Operaciones CRUD asíncronas mediante async/await
- Pluggable JSON parser: la capacidad de utilizar el serializador/deserializador JSON de su elección. Actualmente, el cliente utiliza 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
Cómo conseguirlo
Los binarios están disponibles en S3, el código fuente en Github y los paquetes en Nuget:
Agradecimientos
Al ser un proyecto de código abierto, el SDK .NET de Couchbase depende de las contribuciones, por pequeñas que sean, de la comunidad. Un agradecimiento especial a los siguientes que enviaron pull requests y/o emitieron informes de errores:
- Matt Nischan
- Vojta Jakubec
¡Buen trabajo!
¿Qué pasa con LINQ? No se menciona en ninguna parte de este post, ni siquiera en la sección ¿Qué no hay en esta versión?
Espero que no se haya quedado atrás...
Hola Doron -
El proyecto Linq2Couchbase está vivo y coleando, aunque es una capa separada sobre el SDK. Puedes encontrarlo aquí: https://github.com/couchbasela…
Tenga en cuenta que todavía no he actualizado los paquetes nuget a beta2, por lo que probablemente no funcionará hasta que se actualice; hay algunos cambios estructurales que lo romperán.
¡Gracias!
Jeff