En esta clase aprenderemos cómo guardar y recuperar datos de los Granos en bases de datos reales, utilizando Orleans con SQL Server y MongoDB.
Objetivos de la Clase
- Comprender cómo Orleans maneja el almacenamiento en bases de datos.
- Configurar Orleans para persistencia en SQL Server y MongoDB.
- Implementar Granos con almacenamiento persistente en BD.
- Probar la conexión y recuperación de datos.
¿Cómo Orleans Guarda Datos en Bases de Datos?
Orleans permite persistir los datos de los Granos en una base de datos externa. Esto significa que:
- Un Grano puede almacenar su estado en SQL Server, MongoDB, Azure Table Storage, DynamoDB, entre otros.
- Cuando el Grano se desactiva, sus datos no se pierden.
- Cuando el Grano se reactiva, recupera automáticamente su estado.
Flujo de trabajo en Orleans con Base de Datos
- El Grano modifica su estado.
- Orleans guarda los cambios en la BD.
- Cuando el Grano se desactiva y se reactiva, recupera su estado desde la BD.
Configurar Persistencia con SQL Server
1. Instalar Dependencias
Ejecuta en la Consola del Administrador de Paquetes en OrleansDemo
:
dotnet add package Microsoft.Orleans.Persistence.AdoNet
dotnet add package System.Data.SqlClient
2. Configurar SQL Server como Almacenamiento en Orleans
Edita Program.cs
en OrleansDemo y agrega la configuración de SQL Server:
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();
builder.AddAdoNetGrainStorage("sqlStore", options =>
{
options.Invariant = "System.Data.SqlClient";
options.ConnectionString = "Server=localhost;Database=OrleansDB;User Id=sa;Password=YourPassword;";
});
})
.Build();
await host.RunAsync();
}
}
3. Crear la Base de Datos en SQL Server
Ejecuta este script en SQL Server para crear la base de datos:
CREATE DATABASE OrleansDB;
USE OrleansDB;
CREATE TABLE OrleansStorage (
GrainId NVARCHAR(255) PRIMARY KEY,
GrainType NVARCHAR(255),
State VARBINARY(MAX)
);
4. Implementar un Grano con Persistencia en SQL Server
Interfaz del Grano
using System.Threading.Tasks;
using Orleans;
public interface ICounterGrain : IGrainWithGuidKey
{
Task Increment();
Task<int> GetValue();
}
Implementación del Grano
using System.Threading.Tasks;
using Orleans;
using Orleans.Runtime;
public class CounterGrain : Grain, ICounterGrain
{
private readonly IPersistentState<CounterState> _state;
public CounterGrain([PersistentState("counter", "sqlStore")] IPersistentState<CounterState> state)
{
_state = state;
}
public async Task Increment()
{
_state.State.Value++;
await _state.WriteStateAsync(); // Guarda en SQL Server
}
public Task<int> GetValue()
{
return Task.FromResult(_state.State.Value);
}
}
public class CounterState
{
public int Value { get; set; } = 0;
}
Configurar Persistencia con MongoDB
1. Instalar Dependencias
Ejecuta en OrleansDemo:
dotnet add package Microsoft.Orleans.Persistence.MongoDB
dotnet add package MongoDB.Driver
2. Configurar MongoDB en Orleans
Edita Program.cs
en OrleansDemo:
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();
builder.AddMongoDBGrainStorage("mongoStore", options =>
{
options.DatabaseName = "OrleansDB";
options.ConnectionString = "mongodb://localhost:27017";
});
})
.Build();
await host.RunAsync();
}
}
3. Crear una Base de Datos en MongoDB
Ejecuta en MongoDB Shell:
use OrleansDB;
db.createCollection("OrleansStorage");
4. Implementar un Grano con Persistencia en MongoDB
Interfaz del Grano
using System.Threading.Tasks;
using Orleans;
public interface IUserGrain : IGrainWithGuidKey
{
Task SetName(string name);
Task<string> GetName();
}
Implementación del Grano
using System.Threading.Tasks;
using Orleans;
using Orleans.Runtime;
public class UserGrain : Grain, IUserGrain
{
private readonly IPersistentState<UserState> _state;
public UserGrain([PersistentState("user", "mongoStore")] IPersistentState<UserState> state)
{
_state = state;
}
public async Task SetName(string name)
{
_state.State.Name = name;
await _state.WriteStateAsync(); // Guarda en MongoDB
}
public Task<string> GetName()
{
return Task.FromResult(_state.State.Name);
}
}
public class UserState
{
public string Name { get; set; } = "Desconocido";
}
Probar el Código
Paso 1: Iniciar el Silo
Ejecuta OrleansDemo.
Paso 2: Ejecutar el Cliente
Ejecuta OrleansClient y prueba:
var userGrain = client.GetGrain<IUserGrain>(Guid.NewGuid());
await userGrain.SetName("Carlos");
string name = await userGrain.GetName();
Console.WriteLine($"Nombre guardado: {name}");
Si el Silo se reinicia, el nombre sigue almacenado.
Cuestionario de Autoevaluación
- ¿Cómo Orleans maneja la persistencia de datos en bases de datos externas?
- ¿Cuál es la diferencia entre almacenar datos en SQL Server y MongoDB en Orleans?
- ¿Qué hace la interfaz
IPersistentState<T>
en un Grano Orleans? - ¿Cómo se configura Orleans para usar SQL Server como almacenamiento?
- ¿Qué sucede si reiniciamos el Silo en un sistema sin persistencia configurada?
Resumen de la Clase
- Orleans permite almacenar datos en SQL Server y MongoDB utilizando
IPersistentState<T>
. - Configuramos Orleans para persistir estados en una base de datos.
- Creamos Granos con almacenamiento persistente y verificamos que los datos se mantuvieran después de un reinicio.
- Probamos la persistencia ejecutando Orleans con SQL Server y MongoDB.
Próxima Clase: Seguridad y Autenticación
En la siguiente clase, aprenderemos cómo proteger Orleans con autenticación y autorización.