Eventos
Crie aplicativos e agentes de IA
17 de mar., 21 - 21 de mar., 10
Junte-se à série de encontros para criar soluções de IA escaláveis com base em casos de uso do mundo real com outros desenvolvedores e especialistas.
Registrar agoraNão há mais suporte para esse navegador.
Atualize o Microsoft Edge para aproveitar os recursos, o suporte técnico e as atualizações de segurança mais recentes.
O runtime do Orleans fornece dois mecanismos, chamados de temporizadores e lembretes, que permitem que o desenvolvedor especifique o comportamento periódico para a granularidade.
Os temporizadores são usados para criar um comportamento periódico da granularidade que não é necessário para abranger várias ativações (instanciações da granularidade). Um temporizador é idêntico à classe .NET System.Threading.Timer padrão. Além disso, os temporizadores estão sujeitos a garantias de execução de thread único dentro da ativação de granularidade em que operam.
Cada ativação pode ter nenhum ou mais temporizadores associados. O runtime executa cada rotina de temporizador no contexto de runtime da ativação à qual está associado.
Para iniciar um temporizador, use o método RegisterGrainTimer
, que retorna uma referência IGrainTimer:
protected IGrainTimer RegisterGrainTimer<TState>(
Func<TState, CancellationToken, Task> callback, // function invoked when the timer ticks
TState state, // object to pass to callback
GrainTimerCreationOptions options) // timer creation options
Para cancelar o temporizador, descarte-o.
Um temporizador deixará de ser disparado, se a granularidade for desativada ou quando ocorrer uma falha e o silo falhar.
Considerações importantes:
Grain.RegisterGrainTimer
é a quantidade de tempo que passa desde o momento em que o Task
retornado por callback
é resolvido até o momento em que a próxima invocação de callback
deve ocorrer. Isso não só impossibilita a sobreposição de chamadas sucessivas para callback
, como também faz com que o tempo que callback
leva para ser concluído afete a frequência em que callback
é invocado. Esse é um desvio importante da semântica de System.Threading.Timer.callback
é entregue a uma ativação em uma rodada diferente e nunca será executada simultaneamente com outras rodadas na mesma ativação.Os lembretes são semelhantes aos temporizadores, com algumas diferenças importantes:
Como são persistentes, os lembretes dependem do armazenamento para funcionar. Você deve especificar qual suporte de armazenamento deve ser usado para que o subsistema de lembretes funcione. Você pode fazer isso configurando um dos provedores de lembrete usando os métodos de extensão Use{X}ReminderService
, em que X
é o nome do provedor, por exemplo, UseAzureTableReminderService.
Configuração da Tabela do Azure:
// TODO replace with your connection string
const string connectionString = "YOUR_CONNECTION_STRING_HERE";
var silo = new HostBuilder()
.UseOrleans(builder =>
{
builder.UseAzureTableReminderService(connectionString)
})
.Build();
SQL:
const string connectionString = "YOUR_CONNECTION_STRING_HERE";
const string invariant = "YOUR_INVARIANT";
var silo = new HostBuilder()
.UseOrleans(builder =>
{
builder.UseAdoNetReminderService(options =>
{
options.ConnectionString = connectionString; // Redacted
options.Invariant = invariant;
});
})
.Build();
Se você deseja apenas que uma implementação de lembretes de espaço reservado funcione, sem precisar configurar uma conta do Azure ou um banco de dados SQL, isso fornecerá uma implementação somente de desenvolvimento do sistema de lembretes:
var silo = new HostBuilder()
.UseOrleans(builder =>
{
builder.UseInMemoryReminderService();
})
.Build();
Importante
Se você tiver um cluster heterogêneo, em que os silos manipulam diferentes tipos de grãos (implementam diferentes interfaces), cada silo deverá adicionar a configuração para Lembretes, mesmo que o silo em si não manipule nenhum lembrete.
A granularidade que usa lembretes deve implementar o método IRemindable.ReceiveReminder.
Task IRemindable.ReceiveReminder(string reminderName, TickStatus status)
{
Console.WriteLine("Thanks for reminding me-- I almost forgot!");
return Task.CompletedTask;
}
Para iniciar um lembrete, use o método Grain.RegisterOrUpdateReminder, que retorna um objeto IGrainReminder:
protected Task<IGrainReminder> RegisterOrUpdateReminder(
string reminderName,
TimeSpan dueTime,
TimeSpan period)
reminderName
: é uma cadeia de caracteres que deve identificar exclusivamente o lembrete no escopo da granularidade contextual.dueTime
: especifica o tempo de espera para emitir o tique do primeiro temporizador.period
: especifica o período do temporizador.Como os lembretes sobrevivem pelo tempo de vida de qualquer ativação única, eles devem ser cancelados explicitamente (em vez de serem descartados). Cancele um lembrete chamando Grain.UnregisterReminder:
protected Task UnregisterReminder(IGrainReminder reminder)
O objeto reminder
é o objeto identificador retornado por Grain.RegisterOrUpdateReminder.
Não há garantia de que as instâncias de IGrainReminder
sejam válidas após o tempo de vida de uma ativação. Se você quiser identificar um lembrete de uma maneira que persista, use uma cadeia de caracteres que contenha o nome do lembrete.
Se você tiver apenas o nome do lembrete e precisar da instância correspondente de IGrainReminder
, chame o método Grain.GetReminder:
protected Task<IGrainReminder> GetReminder(string reminderName)
Recomendamos que você use os temporizadores nas seguintes circunstâncias:
Recomendamos que você use os lembretes nas seguintes circunstâncias:
Você pode usar uma combinação de lembretes e temporizadores para atingir sua meta. Por exemplo, se você precisar de um temporizador com uma pequena resolução que precise sobreviver em todas as ativações, você pode usar um lembrete executado a cada cinco minutos, cujo objetivo é ativar a granularidade que reinicia um temporizador local que pode ter sido perdido devido à desativação.
Para registrar um temporizador ou lembrete com um grão POCO, implemente a interface IGrainBase e injete o ITimerRegistry ou o IReminderRegistry no construtor do grão.
using Orleans.Timers;
namespace Timers;
public sealed class PingGrain : IGrainBase, IPingGrain, IDisposable
{
private const string ReminderName = "ExampleReminder";
private readonly IReminderRegistry _reminderRegistry;
private IGrainReminder? _reminder;
public IGrainContext GrainContext { get; }
public PingGrain(
ITimerRegistry timerRegistry,
IReminderRegistry reminderRegistry,
IGrainContext grainContext)
{
// Register timer
timerRegistry.RegisterGrainTimer(
grainContext,
callback: static async (state, cancellationToken) =>
{
// Omitted for brevity...
// Use state
await Task.CompletedTask;
},
state: this,
options: new GrainTimerCreationOptions
{
DueTime = TimeSpan.FromSeconds(3),
Period = TimeSpan.FromSeconds(10)
});
_reminderRegistry = reminderRegistry;
GrainContext = grainContext;
}
public async Task Ping()
{
_reminder = await _reminderRegistry.RegisterOrUpdateReminder(
callingGrainId: GrainContext.GrainId,
reminderName: ReminderName,
dueTime: TimeSpan.Zero,
period: TimeSpan.FromHours(1));
}
void IDisposable.Dispose()
{
if (_reminder is not null)
{
_reminderRegistry.UnregisterReminder(
GrainContext.GrainId, _reminder);
}
}
}
O código anterior:
IPingGrain
e IDisposable.Ping
é chamado, registra um lembrete que é invocado a cada hora e começa imediatamente após o registro.Dispose
cancelará o lembrete se ele estiver registrado.Comentários do .NET
O .NET é um projeto código aberto. Selecione um link para fornecer comentários:
Eventos
Crie aplicativos e agentes de IA
17 de mar., 21 - 21 de mar., 10
Junte-se à série de encontros para criar soluções de IA escaláveis com base em casos de uso do mundo real com outros desenvolvedores e especialistas.
Registrar agora