Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Kod yazmadan önce bir grain sınıfını uygulamak için, .NET Standard veya .NET Core'u (tercih edilen) ya da bağımlılıklar nedeniyle .NET Standard veya .NET Core kullanamıyorsanız .NET Framework 4.6.1 veya daha yüksek bir sürümünü hedefleyen yeni bir Class Library projesi oluşturun. Arabirimlerin uygulamadan daha iyi ayrılması için aynı Sınıf Kitaplığı projesinde veya iki farklı projede taneli arabirimler ve tanecik sınıfları tanımlayabilirsiniz. Her iki durumda da, projelerin Microsoft'a başvurması gerekir..Orleans. Sdk NuGet paketi.
Daha ayrıntılı yönergeler içinOrleans bölümüne bakın.
Grain arabirimler ve sınıflar
Tanecikler birbirleriyle etkileşim kurar ve dışarıdan, kendi tanecik arabirimlerinin bir parçası olarak bildirilen yöntemleri çağırarak etkileşimde bulunur. Bir taneli sınıf, önceden bildirilen bir veya daha fazla tanecik arabirimi uygular. Bir taneli arabirimindeki tüm yöntemler, bir Task (yöntemler için void), bir Task<TResult> veya bir ValueTask<TResult> (tür T değerlerini döndüren yöntemler için) döndürmelidir.
Varlık Hizmeti örneğinden bir alıntı Orleans verilmiştir aşağıda:
public interface IPlayerGrain : IGrainWithGuidKey
{
Task<IGameGrain> GetCurrentGame(CancellationToken cancellationToken = default);
Task JoinGame(IGameGrain game, CancellationToken cancellationToken = default);
Task LeaveGame(IGameGrain game, CancellationToken cancellationToken = default);
}
public class PlayerGrain : Grain, IPlayerGrain
{
private IGameGrain _currentGame;
// Game the player is currently in. May be null.
public Task<IGameGrain> GetCurrentGame(CancellationToken cancellationToken = default)
{
return Task.FromResult(_currentGame);
}
// Game grain calls this method to notify that the player has joined the game.
public Task JoinGame(IGameGrain game, CancellationToken cancellationToken = default)
{
_currentGame = game;
Console.WriteLine(
$"Player {GetPrimaryKey()} joined game {game.GetPrimaryKey()}");
return Task.CompletedTask;
}
// Game grain calls this method to notify that the player has left the game.
public Task LeaveGame(IGameGrain game, CancellationToken cancellationToken = default)
{
_currentGame = null;
Console.WriteLine(
$"Player {GetPrimaryKey()} left game {game.GetPrimaryKey()}");
return Task.CompletedTask;
}
}
Tahıl yöntemleri için yanıt zaman aşımı süresi
Çalışma zamanı, Orleans her bir gren yöntemi için yanıt zaman aşımı uygulamanıza olanak tanır. Zaman aşımı içinde bir taneli yöntem tamamlanmazsa, çalışma zamanı bir TimeoutExceptionoluşturur. Yanıt zaman aşımı uygulamak için ResponseTimeoutAttribute öğesini arabirimin grain yöntemi tanımına ekleyin. Hem istemcinin hem de silonun zaman aşımının farkında olması gerektiğinden, özniteliğini tahıl sınıfındaki yöntem uygulamasına değil arabirim yöntemi tanımına eklemek çok önemlidir.
Önceki PlayerGrain uygulamasını genişleten aşağıdaki örnekte, LeaveGame yöntemine yanıt zaman aşımı nasıl uygulanacağı gösterilmektedir.
public interface IPlayerGrain : IGrainWithGuidKey
{
Task<IGameGrain> GetCurrentGame(CancellationToken cancellationToken = default);
Task JoinGame(IGameGrain game, CancellationToken cancellationToken = default);
[ResponseTimeout("00:00:05")] // 5s timeout
Task LeaveGame(IGameGrain game, CancellationToken cancellationToken = default);
}
Yukarıdaki kod, LeaveGame yönteminde beş saniyelik bir yanıt zaman aşımı ayarlar. Bir oyundan ayrıldığınızda, beş saniyeden fazla sürerse bir TimeoutException gönderilir.
Zaman aşımını TimeSpan oluşturucu parametrelerini kullanarak da belirtebilirsiniz.
public interface IDataProcessingGrain : IGrainWithGuidKey
{
// 2 minute timeout using hours, minutes, seconds
[ResponseTimeout(0, 2, 0)]
Task<ProcessingResult> ProcessLargeDatasetAsync(Dataset data, CancellationToken cancellationToken = default);
// 500ms timeout using TimeSpan.FromMilliseconds equivalent
[ResponseTimeout("00:00:00.500")]
Task<HealthStatus> GetHealthAsync(CancellationToken cancellationToken = default);
}
Yanıt zaman aşımını yapılandırma
Bireysel taneli yöntem yanıt zaman aşımlarına benzer şekilde, tüm yöntemler için varsayılan bir yanıt zaman aşımını yapılandırabilirsiniz. Belirtilen süre içinde yanıt alınmazsa, grain yöntemlerine çağrılar zaman aşımına uğrar. Varsayılan olarak, bu süre 30 saniyedir. Varsayılan yanıt zaman aşımını yapılandırabilirsiniz:
- Bir dış istemcide ResponseTimeout üzerinde ClientMessagingOptions'yı yapılandırarak.
- Bir sunucuda, ResponseTimeout üzerinde SiloMessagingOptions yapılandırarak.
yapılandırması Orleanshakkında daha fazla bilgi için bkz. İstemci yapılandırması veya Sunucu yapılandırması.
Zaman aşımı en iyi uygulamaları
Zaman aşımlarını yapılandırırken aşağıdakileri göz önünde bulundurun:
- Yöntem başına zaman aşımları genel ayarları geçersiz kılar: Bir yöntem üzerinde bir ResponseTimeoutAttribute , genel ResponseTimeoutAttribute yapılandırmasına göre önceliklidir.
- Gerçekçi zaman aşımları ayarlayın: Beklenen yürütme süresine ve makul ağ gecikme süresine göre temel zaman aşımları. Çok kısa zaman aşımları gereksiz başarısızlıklara neden olur; çok uzun zaman aşımları hata algılamayı geciktirir.
- Uzun süre çalışan işlemler: Önemli zaman alabilen işlemler için, zaman Orleans süresiz olarak uzatmak yerine Anımsatıcılar kullanmayı göz önünde bulundurun.
- Test: Uygulamanızın TimeoutException durumunu nazikçe ele alabilmesi için tümleştirme testlerinizde test zaman aşımı davranışını test edin.
Tahıl yöntemlerinden geri dönüş değerleri
Bir tanecik arabiriminde, türü T olan bir değeri Task<TResult> olarak döndüren bir tanecik yöntemi tanımlayın.
anahtar sözcüğüyle async işaretlenmemiş tanecik yöntemleri için, dönüş değeri kullanılabilir olduğunda genellikle aşağıdaki deyimi kullanarak döndürürsiniz:
public Task<SomeType> GrainMethod1()
{
return Task.FromResult(GetSomeType());
}
Bir tanecik arabiriminde, değer döndürmeyen (etkili bir şekilde geçersiz bir yöntem) Task döndüren bir tanecik yöntemi tanımlayın. döndürülen Task , zaman uyumsuz yürütmeyi ve yöntemin tamamlanmasını gösterir. anahtar sözcüğüyle async işaretlenmemiş tanecik yöntemleri için bir "void" yöntemi yürütmesini tamamladığında özel değerini Task.CompletedTaskdöndürmesi gerekir:
public Task GrainMethod2()
{
return Task.CompletedTask;
}
async ile işaretlenmiş bir basit yöntem, değeri doğrudan döndürür:
public async Task<SomeType> GrainMethod3()
{
return await GetSomeTypeAsync();
}
void olarak async işaretlenen bir taneli yöntem, yürütmesi tamamlandığında hiçbir değer döndürmeden sona erer.
public async Task GrainMethod4()
{
return;
}
Bir taneli yöntem başka bir zaman uyumsuz yöntem çağrısından (bir taneye veya bir taneye) dönüş değeri alırsa ve bu çağrı için hata işleme gerçekleştirmesi gerekmiyorsa, yalnızca bu zaman uyumsuz çağrıdan aldığı değeri döndürebilir Task :
public Task<SomeType> GrainMethod5()
{
Task<SomeType> task = CallToAnotherGrain();
return task;
}
Benzer şekilde, bir void taneli yöntem, beklemek yerine başka bir Task çağrı tarafından ona döndürülen bir değeri döndürebilir.
public Task GrainMethod6()
{
Task task = CallToAsyncAPI();
return task;
}
ValueTask<TResult> yerine Task<TResult>kullanılabilir.
IAsyncEnumerable türüne ait dönüş değerleri
Orleans, tanecik yöntemlerinden IAsyncEnumerable<T> döndürmeyi destekleyerek tüm sonuç kümesini belleğe yüklemeden çağırana doğrudan ve verimli bir veri akışı sağlar. Bu, aşağıdaki gibi senaryolar için kullanışlıdır:
- Büyük veri koleksiyonlarını aşamalı olarak döndürme
- Gerçek zamanlı güncelleştirmeleri akışla aktarma
- Sonuçlar kullanılabilir hale geldikçe işleniyor
Akış dilimi arabirimi tanımlama
public interface IDataGrain : IGrainWithStringKey
{
// Returns a streaming sequence of items
IAsyncEnumerable<DataItem> GetAllItemsAsync();
// Can also include CancellationToken for cancellation support
IAsyncEnumerable<DataItem> GetItemsAsync(CancellationToken cancellationToken = default);
}
Akış yöntemini uygulama
yield return deyimini kullanın veya doğrudan IAsyncEnumerable<T>'i döndürün.
public class DataGrain : Grain, IDataGrain
{
public async IAsyncEnumerable<DataItem> GetAllItemsAsync()
{
for (int i = 0; i < 1000; i++)
{
// Simulate async data retrieval
var item = await FetchItemAsync(i);
yield return item;
}
}
public async IAsyncEnumerable<DataItem> GetItemsAsync(
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
int id = 0;
while (!cancellationToken.IsCancellationRequested)
{
var item = await FetchItemAsync(id++);
yield return item;
}
}
private Task<DataItem> FetchItemAsync(int id) =>
Task.FromResult(new DataItem { Id = id });
}
[GenerateSerializer]
public class DataItem
{
[Id(0)]
public int Id { get; set; }
}
Akış yöntemini kullanma
var grain = client.GetGrain<IDataGrain>("mydata");
await foreach (var item in grain.GetAllItemsAsync())
{
Console.WriteLine($"Received item: {item.Id}");
// Process each item as it arrives
await ProcessItemAsync(item);
}
Toplu iş boyutunu yapılandırma
Orleans ağ gidiş dönüşlerini azaltmak için birden çok öğeyi bir araya toplar.
WithBatchSize uzantı yöntemini kullanarak toplu iş boyutunu yapılandırabilirsiniz.
// Request up to 50 elements per batch instead of the default 100
await foreach (var item in grain.GetAllItemsAsync().WithBatchSize(50))
{
await ProcessItemAsync(item);
}
IAsyncEnumerable ve Streams karşılaştırması Orleans
| Özellik | IAsyncEnumerable | Orleans Akışlar |
|---|---|---|
| Kullanım örneği | İstek-yanıt veri akışı | Pub-sub mesajlaşması |
| Ömür | Kapsamı tek çağrı olarak belirlenmiş | Kalıcı abonelikler |
| Yön | Yalnızca arayan kişiye kısıtlama | Herhangi bir aboneye herhangi bir üretici |
| Backpressure | Built-in | Sağlayıcıya bağımlı |
| Kalıcılık | Hayı | İsteğe bağlı (sağlayıcıya bağımlı) |
Şu durumlarda kullanın IAsyncEnumerable<T> :
- Akış sonuçları içeren basit bir istek-yanıt deseni gerekir
- Çağıran veri akışını başlatır ve tüm sonuçları tüketir
- Otomatik geri baskı ve iptal desteği istiyorsunuz
Orleans Akışları aşağıdaki durumlarda kullanın:
- Birden çok aboneye sahip bir pub-sub mesajlaşmasına ihtiyacınız var.
- Abonelikler, yapı birimi devre dışı bırakılsa da korunmalıdır
- Kalıcı veya dayanıklı akışlara ihtiyacınız var
Taneli başvurular
"Bir grain başvurusu, karşılık gelen grain sınıfıyla aynı grain arabirimini uygulayan bir proxy nesnesidir." Hedef birimin mantıksal kimliğini (tür ve benzersiz anahtar) kapsüller. Hedef taneciğe çağrı yapmak için tanecik referansları kullanırsınız. Her tanecik başvurusu tek bir taneye (tek bir tanecik sınıfı örneği) işaret eder, ancak aynı taneye birden çok bağımsız başvuru oluşturabilirsiniz.
Bir tane referansı hedef tanenin mantıksal kimliğini temsil ettiğinden, tanenin fiziksel konumundan bağımsızdır ve sistem tamamen yeniden başlatıldıktan sonra bile geçerli kalır. Diğer tüm .NET nesneleri gibi tanecik başvurularını kullanabilirsiniz. Bunu bir yönteme geçirebilir, yöntem dönüş değeri olarak kullanabilir ve hatta kalıcı depolama alanına kaydedebilirsiniz.
Tahılın kimliğini IGrainFactory.GetGrain<TGrainInterface>(Type, Guid) yöntemine geçirerek bir tahıl referansı elde edebilirsiniz; burada T tahıl arayüzüdür ve key türü içindeki tahılın benzersiz anahtarıdır.
Aşağıdaki örnekler, daha önce tanımlanan IPlayerGrain arabirimi için bir "grain reference"ın nasıl elde edileceğini göstermektedir.
Bir tahıl sınıfından:
IPlayerGrain player = GrainFactory.GetGrain<IPlayerGrain>(playerId);
İstemci kodundan Orleans.
IPlayerGrain player = client.GetGrain<IPlayerGrain>(playerId);
Daha fazla bilgi için bkz. tahıl referans makalesi.
Grenli yöntem çağırma
Programlama Orleans modeli zaman uyumsuz programlamayı temel alır. Bir önceki örnekte verilen tanecik referansını kullanarak, bir tanecik yöntem çağrısını şu şekilde gerçekleştirebilirsiniz:
// Invoking a grain method asynchronously
Task joinGameTask = player.JoinGame(this, GrainCancellationToken);
// The await keyword effectively makes the remainder of the
// method execute asynchronously at a later point
// (upon completion of the Task being awaited) without blocking the thread.
await joinGameTask;
// The next line will execute later, after joinGameTask has completed.
players.Add(playerId);
İki veya daha fazla Tasks nesnesine katılabilirsiniz. Birleştirme işlemi, tüm bileşenlerinin Task tamamlandığında çözülecek yeni bir Tasks oluşturur. Bu desen, bir birimin birden çok hesaplama başlatması ve devam etmeden önce tümünün tamamlanmasını beklemesi gerektiğinde kullanışlıdır. Örneğin, birçok parçadan oluşan bir web sayfası oluşturan bir ön uç modülü, birden fazla arka uç çağrısı yapabilir (her bir parça için birer tane) ve her sonuç için bir Task alabilir. Tahıl daha sonra tüm bunların Tasksbirleşmesini beklerdi. Katılan Task çözümlendiğinde, her bir Tasks tamamlanır ve web sayfasını biçimlendirmek için gereken tüm veriler alınmış olur.
Örnek:
List<Task> tasks = new List<Task>();
Message notification = CreateNewMessage(text);
foreach (ISubscriber subscriber in subscribers)
{
tasks.Add(subscriber.Notify(notification));
}
// WhenAll joins a collection of tasks, and returns a joined
// Task that will be resolved when all of the individual notification Tasks are resolved.
Task joinedTask = Task.WhenAll(tasks);
await joinedTask;
// Execution of the rest of the method will continue
// asynchronously after joinedTask is resolve.
Hata yayılımı
Bir taneli yöntem bir özel durumu fırlattığında, Orleans bu özel durumu, gerektiğinde ara sunucularda, çağrı yığını boyunca iletir. Bunun amaçlandığı gibi çalışması için özel durumların Orleans tarafından serileştirilebilir olması ve özel durumu işleyen konakların özel durum türünün mevcut olması gerekir. Bir özel durum türü yoksa, Orleans özgün özel durumun iletisini, türünü ve yığın izlemesini koruyarak örneği Orleans.Serialization.UnavailableExceptionFallbackException olarak özel durumu fırlatır.
Grain yöntemlerinden fırlatılan özel durumlar, özel durum Orleans.Storage.InconsistentStateException öğesinden devralmadığı sürece taneciğin devre dışı bırakılmasına neden olmaz. Depolama işlemleri, tanenin bellek içi durumunun veritabanındaki durumla tutarsız olduğunu keşfettiklerinde InconsistentStateException oluşturur. Özel işleme InconsistentStateException'in yanı sıra, bu davranış herhangi bir .NET nesnesinden istisna fırlatmaya benzer: İstisnalar, bir nesnenin yok edilmesine neden olmaz.
Sanal yöntemler
Bir tahıl sınıfı, OnActivateAsync ve OnDeactivateAsync sanal yöntemlerini isteğe bağlı olarak geçersiz kılabilir. Çalışma zamanı, sınıfın Orleans her bir taneciğinin etkinleştirilmesi ve devre dışı bırakılması sırasında bu yöntemleri çağırır. Bu, tahıl kodunuz için ek başlatma ve temizleme işlemleri gerçekleştirme şansı verir. OnActivateAsync tarafından oluşan bir özel durum, etkinleştirme sürecini başarısız kılar.
( OnActivateAsync Geçersiz kılınırsa) her zaman tahıl etkinleştirme işleminin bir parçası olarak çağrılırken, OnDeactivateAsync her durumda (örneğin, bir sunucu hatası veya diğer anormal olaylar) çağrılacağı garanti edilemez. Bu nedenle, uygulamalarınız kalıcı durum değişiklikleri gibi kritik işlemleri gerçekleştirmek için güvenmemelidir OnDeactivateAsync . Bunu yalnızca en iyi efor işlemleri için kullanın.