0

Microsoft Orleans #04: Comunicación entre Granos

En esta clase aprenderemos cómo los Granos en Orleans pueden comunicarse entre sí para intercambiar datos y coordinar tareas.

Objetivos de la Clase

  • Comprender cómo un Grano puede llamar a otro Grano en Orleans.
  • Implementar un Grano Maestro que se comunica con Granos Subordinados.
  • Probar la comunicación entre Granos en un ejemplo práctico.

¿Cómo se comunican los Granos en Orleans?

A diferencia de los objetos tradicionales en C#, los Granos en Orleans no se instancian directamente. En su lugar, Orleans gestiona su ciclo de vida automáticamente y los Granos se acceden mediante el GrainFactory.

Métodos de comunicación entre Granos

  1. Llamadas directas entre Granos: Un Grano obtiene una referencia a otro Grano y lo llama mediante GetGrain<T>().
  2. Comunicación basada en eventos: Los Granos pueden utilizar Orleans Streams para enviar eventos a múltiples suscriptores.
  3. Persistencia compartida: Los Granos pueden compartir información a través de almacenamiento persistente.

Ejemplo de flujo de comunicación

  1. Un Grano Maestro obtiene referencias a varios Granos Subordinados.
  2. El Maestro envía tareas a los Subordinados.
  3. Los Subordinados procesan la tarea y devuelven resultados al Maestro.

Implementar la comunicación entre Granos

Definir la interfaz del Grano Subordinado

Crea ISubordinadoGrain.cs en la carpeta Granos:

using System.Threading.Tasks;
using Orleans;

public interface ISubordinadoGrain : IGrainWithStringKey
{
    Task<string> ProcesarTarea(string tarea);
}

Implementar el Grano Subordinado

Crea SubordinadoGrain.cs en la carpeta Granos:

using System;
using System.Threading.Tasks;
using Orleans;

public class SubordinadoGrain : Grain, ISubordinadoGrain
{
    public Task<string> ProcesarTarea(string tarea)
    {
        Console.WriteLine($"Subordinado procesando tarea: {tarea}");
        return Task.FromResult($"Tarea '{tarea}' completada por {this.GetPrimaryKeyString()}");
    }
}

Definir la interfaz del Grano Maestro

Crea IMaestroGrain.cs en la carpeta Granos:

using System.Threading.Tasks;
using Orleans;

public interface IMaestroGrain : IGrainWithStringKey
{
    Task<string> AsignarTarea(string idSubordinado, string tarea);
}

Implementar el Grano Maestro

Crea MaestroGrain.cs en la carpeta Granos:

using System.Threading.Tasks;
using Orleans;

public class MaestroGrain : Grain, IMaestroGrain
{
    public async Task<string> AsignarTarea(string idSubordinado, string tarea)
    {
        var subordinado = GrainFactory.GetGrain<ISubordinadoGrain>(idSubordinado);
        string resultado = await subordinado.ProcesarTarea(tarea);
        return resultado;
    }
}

Explicación del código

  • GetGrain<ISubordinadoGrain>(idSubordinado): El Grano Maestro obtiene una referencia al Grano Subordinado mediante su ID.
  • ProcesarTarea(tarea): Llama al método del Subordinado para realizar la tarea.
  • El resultado se devuelve al Maestro.

Configurar el Silo para ejecutar los Granos

Edita Program.cs en OrleansDemo para asegurarte de que Orleans gestiona los Granos correctamente:

using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Orleans;
using Orleans.Hosting;

class Program
{
    static async Task Main(string[] args)
    {
        var host = Host.CreateDefaultBuilder()
            .UseOrleans(builder =>
            {
                builder.UseLocalhostClustering();
            })
            .Build();

        await host.RunAsync();
    }
}

Probar la comunicación entre Granos

Edita Program.cs en OrleansClient para probar la comunicación entre Maestro y Subordinado:

using System;
using System.Threading.Tasks;
using Orleans;
using Orleans.Hosting;

class Program
{
    static async Task Main(string[] args)
    {
        var client = new ClientBuilder()
            .UseLocalhostClustering()
            .Build();

        await client.Connect();
        Console.WriteLine("Cliente conectado a Orleans.");

        var maestro = client.GetGrain<IMaestroGrain>("maestro1");
        string resultado = await maestro.AsignarTarea("subordinado1", "Revisión de código");

        Console.WriteLine($"Resultado de la tarea: {resultado}");
    }
}

Explicación del código

  1. El Cliente obtiene una referencia al Grano Maestro.
  2. El Maestro asigna una tarea a un Grano Subordinado.
  3. El Subordinado procesa la tarea y devuelve el resultado al Cliente.

Salida esperada en consola

Cliente conectado a Orleans.
Subordinado procesando tarea: Revisión de código
Resultado de la tarea: Tarea 'Revisión de código' completada por subordinado1

Si ves este resultado, la comunicación entre los Granos funciona correctamente.

Cuestionario de Autoevaluación

  1. ¿Cómo obtiene un Grano una referencia a otro Grano en Orleans?
  2. ¿Por qué los Granos no se instancian directamente en Orleans?
  3. ¿Cuál es la diferencia entre un Grano Maestro y un Grano Subordinado?
  4. ¿Cómo se usa GetGrain<T>() para llamar a otro Grano?
  5. ¿Qué sucede si intentamos llamar a un Grano que nunca ha sido activado antes?

Resumen de la Clase

  • Los Granos en Orleans pueden comunicarse entre sí utilizando GetGrain<T>().
  • Implementamos un Grano Maestro que delega tareas a Granos Subordinados.
  • Probamos la comunicación entre Granos ejecutando una tarea y devolviendo el resultado.
  • La arquitectura distribuida de Orleans gestiona automáticamente la activación y desactivación de Granos.

Próxima Clase: Eventos y Streams

En la siguiente clase, aprenderemos cómo enviar eventos en tiempo real entre Granos utilizando Orleans Streams.

Fernando Sonego

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *