Leer en inglés

Compartir a través de


Streaming con Orleans

Orleans v.1.0.0 ha incorporado compatibilidad con extensiones de streaming al modelo de programación. Las extensiones de streaming proporcionan un conjunto de abstracciones y de API que hacen plantearse el uso de secuencias y trabajar con ellas de forma más sencillo y eficaz. Las extensiones de streaming permiten a los desarrolladores escribir aplicaciones reactivas que operan en una secuencia de eventos de forma estructurada. El modelo de extensibilidad de los proveedores de secuencias hace que el modelo de programación sea compatible y portátil en una amplia gama de tecnologías de puesta en cola existentes, como Event Hubs, ServiceBus, las colas de Azure y Apache Kafka. No es necesario escribir ningún código especial ni ejecutar procesos dedicados para interactuar con estas colas.

¿Por qué debería interesarme?

Si ya lo sabe todo sobre el procesamiento de secuencias y conoce tecnologías como Event Hubs, Kafka, Azure Stream Analytics, Apache Storm, Apache Spark Streaming y las extensiones reactivas (Rx) de .NET, probablemente se pregunte por qué debería interesarle esto. ¿Por qué es necesario otro sistema de procesamiento de secuencias y cómo están relacionados los actores con las secuencias?"¿Por qué usar secuencias de Orleans?" contesta a esa pregunta.

Modelo de programación

Hay varios principios detrás del modelo de programación de secuencias de Orleans:

  1. Las secuencias de Orleans son virtuales. Es decir, siempre hay una secuencia. No se crea ni destruye explícitamente, y nunca puede fallar.
  2. Las secuencias se distinguen mediante identificadores de secuencia, que son simplemente nombres lógicos compuestos de GUID y cadenas.
  3. Las secuencias de Orleans permiten desacoplar la generación de datos de su procesamiento, tanto en el tiempo como en el espacio. Esto significa que el productor de secuencias y el consumidor de secuencias pueden estar en servidores diferentes o en zonas horarias distintas y serán resistentes a errores.
  4. Las secuencias de Orleans son ligeras y dinámicas. El tiempo de ejecución de streaming de Orleans está diseñado para controlar un gran número de secuencias que vienen y van a gran velocidad.
  5. Los enlaces de secuencias de Orleans son dinámicos. El tiempo de ejecución de streaming de Orleans está diseñado para controlar los casos en los que los granos se conectan y desconectan de las secuencias a una gran velocidad.
  6. El tiempo de ejecución de streaming de Orleans administra el ciclo de vida de consumo de secuencias de manera transparente. Una vez que una aplicación se suscribe a una secuencia, recibirá los eventos de esa secuencia, incluso ante la presencia de errores.
  7. Las secuencias de Orleans funcionan uniformemente entre granos y clientes de Orleans.

API de programación

Las aplicaciones interactúan con secuencias mediante Orleans.Streams.IAsyncStream<T>, que implementa las interfaces Orleans.Streams.IAsyncObserver<T> y Orleans.Streams.IAsyncObservable<T>. Estas API son similares a las de sobra conocidas extensiones reactivas (Rx) de .NET.

En el siguiente ejemplo común, un dispositivo genera algunos datos, que se envían como una solicitud HTTP al servicio que se ejecuta en la nube. El cliente de Orleans que se ejecuta en el servidor front-end recibe esta llamada HTTP y publica los datos en una secuencia de dispositivo coincidente:

C#
public async Task OnHttpCall(DeviceEvent deviceEvent)
{
     // Post data directly into the device's stream.
     IStreamProvider streamProvider =
        GrainClient.GetStreamProvider("MyStreamProvider");

    IAsyncStream<DeviceEventData> deviceStream =
        streamProvider.GetStream<DeviceEventData>(
            deviceEvent.DeviceId, "MyNamespace");

     await deviceStream.OnNextAsync(deviceEvent.Data);
}

En este otro ejemplo de abajo, un usuario de chat (implementado como grano de Orleans) se une a un salón de chat, obtiene el identificador de una secuencia de mensajes de chat generados por todos los demás usuarios de esta sala y se suscribe a ella. Cabe mencionar que el usuario de chat no necesita tener conocimiento del grano del salón de chat en sí (es posible que no haya un grano en el sistema) ni de otros usuarios de ese grupo que producen mensajes. Por no mencionar que, para publicar en la secuencia de chat, no es necesario saber quién está suscrito a la secuencia actualmente. Esto demuestra cómo los usuarios de chat se pueden desacoplar completamente en el tiempo y el espacio.

C#
public class ChatUser: Grain
{
    public async Task JoinChat(Guid chatGroupId)
    {
        IStreamProvider streamProvider =
            base.GetStreamProvider("MyStreamProvider");

        IAsyncStream<string> chatStream =
            streamProvider.GetStream<string>(chatGroupId, "MyNamespace");

        await chatStream.SubscribeAsync(
            async (message, token) => Console.WriteLine(message))
    }
}

Ejemplo de inicio rápido

El ejemplo de inicio rápido es una buena forma de conocer rápidamente el flujo de trabajo general de uso de secuencias en la aplicación. Después de verlo, conviene leer las API de programación de secuencias para comprender mejor los conceptos.

API de programación de secuencias

Las API de programación de secuencias proporcionan una descripción detallada de las API de programación.

Proveedores de secuencias

Las secuencias pueden proceder de los canales físicos de diversas formas y maneras, y pueden tener semánticas distintas. El streaming de Orleans está diseñado para dar cabida a toda esta diversidad a través del concepto de proveedores de secuencias, que es un punto de extensibilidad en el sistema. Actualmente, Orleans tiene implementaciones de dos proveedores de secuencias: el proveedor de secuencias de mensaje simple (basado en TCP) y el proveedor de secuencias de cola de Azure (basado en la cola de Azure). Encontrará más detalles sobre los proveedores de secuencias en Proveedores de secuencias.

Semántica de las secuencias

Semántica de suscripción de secuencia:

las secuencias de Orleans garantizan la coherencia secuencial en las operaciones de suscripción de las secuencias. En concreto, cuando un consumidor se suscribe a una secuencia, una vez que el objeto Task que representa la operación de suscripción se ha resuelto correctamente, el consumidor verá todos los eventos que se generaron después haberse suscrito. Además, las secuencias rebobinables permiten suscribirse desde un momento arbitrario en el pasado mediante StreamSequenceToken. Para obtener más información, vea Proveedores de secuencias de Orleans.

Garantías de entrega de eventos de secuencia individuales:

las garantías de entrega de eventos individuales dependen de los proveedores de secuencias individuales. Algunos solo proporcionan entrega una vez como máximo con el mejor esfuerzo (como las secuencias de mensaje simple, o SMS), mientras que otros proporcionan entrega una vez como mínimo (como las secuencias de cola de Azure). Incluso se puede crear un proveedor de secuencias que garantice una entrega exactamente una vez (aún no tenemos un proveedor de este tipo, pero se puede crear uno).

Orden de entrega de eventos:

el orden de los eventos también depende del correspondiente proveedor de secuencias. En las secuencias SMS, el productor controla explícitamente el orden de los eventos vistos por el consumidor mediante el control de la forma en que se publican. Las secuencias de cola de Azure no garantizan el orden FIFO, ya que las colas de Azure subyacentes no garantizan el orden en casos de error. Las aplicaciones también pueden controlar el orden de entrega de secuencias mediante StreamSequenceToken.

Implementación de secuencias

La implementación de secuencias de Orleans proporciona una visión general a grandes rasgos de la implementación interna.

Ejemplos de código

Aquí encontrará más ejemplos de cómo usar las API de streaming en un grano. Tenemos previsto crear más ejemplos en el futuro.

Consulte también