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
- Llamadas directas entre Granos: Un Grano obtiene una referencia a otro Grano y lo llama mediante
GetGrain<T>()
. - Comunicación basada en eventos: Los Granos pueden utilizar Orleans Streams para enviar eventos a múltiples suscriptores.
- Persistencia compartida: Los Granos pueden compartir información a través de almacenamiento persistente.
Ejemplo de flujo de comunicación
- Un Grano Maestro obtiene referencias a varios Granos Subordinados.
- El Maestro envía tareas a los Subordinados.
- 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
- El Cliente obtiene una referencia al Grano Maestro.
- El Maestro asigna una tarea a un Grano Subordinado.
- 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
- ¿Cómo obtiene un Grano una referencia a otro Grano en Orleans?
- ¿Por qué los Granos no se instancian directamente en Orleans?
- ¿Cuál es la diferencia entre un Grano Maestro y un Grano Subordinado?
- ¿Cómo se usa
GetGrain<T>()
para llamar a otro Grano? - ¿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.