3.x'ten Orleans 7.0'a geçiş

Orleans 7.0, barındırma iyileştirmeleri, özel serileştirme, değişmezlik ve tahıl soyutlamaları dahil olmak üzere çeşitli yararlı değişiklikler sunar.

Geçiş

Anımsatıcılar, akışlar veya tane kalıcılığı kullanan mevcut uygulamalar, taneleri ve akışları tanımlama şeklindeki değişiklikler nedeniyle kolayca 7.0'a OrleansOrleans geçirilemez. Bu uygulamalar için artımlı olarak bir geçiş yolu sunmayı planlıyoruz.

Önceki sürümlerini Orleans çalıştıran uygulamalar 7.0'a Orleans sıralı yükseltme yoluyla sorunsuz bir şekilde yükseltilemez. Bu nedenle, yeni bir küme dağıtma ve önceki kümenin yetkisini alma gibi farklı bir yükseltme stratejisi kullanılmalıdır. Orleans7.0, kablo protokolünün uyumsuz bir şekilde değiştirilmesi, kümelerin önceki sürümlerini Orleansçalıştıran 7.0 konak ve konak karışımı Orleans içeremeyeceği anlamına gelir.

Bu tür hataya neden olan değişiklikleri uzun yıllar, hatta büyük sürümlerde bile önledik, neden şimdi? İki önemli neden vardır: kimlikler ve serileştirme. Kimliklerle ilgili olarak, Grain ve stream kimlikleri artık dizelerden oluşuyor, bu da taneciklerin genel tür bilgilerini düzgün bir şekilde kodlamasına ve akışların uygulama etki alanına daha kolay eşlenmesine olanak sağlıyor. Tane türleri daha önce genel tanecikleri temsil emeyen karmaşık bir veri yapısı kullanılarak belirlendi ve bu da köşe durumlarına yol açıyordu. Akışlar, geliştiricilerin uygulama etki alanlarına eşleyemediği ancak verimli olduğu bir stringGuid ad alanı ve anahtar tarafından belirlendi. Serileştirme artık sürüme dayanıklıdır; başka bir deyişle, türlerinizi belirli uyumlu yollarla değiştirebilir, bir dizi kuralı izleyebilir ve serileştirme hatası olmadan uygulamanızı yükseltebileceğinizden emin olabilirsiniz. Uygulama türleri akışlarda veya tahıl depolamada kalıcı hale geldiğinde bu durum özellikle sorunluydu. Aşağıdaki bölümlerde önemli değişiklikler ayrıntılı olarak açıklanmıştır ve bunlar daha ayrıntılı olarak tartışılmaktadır.

Paketleme değişiklikleri

Bir projeyi 7.0'a Orleans yükseltiyorsanız aşağıdaki eylemleri gerçekleştirmeniz gerekir:

İpucu

Orleans Tüm örnekler 7.0'a Orleans yükseltilmiştir ve yapılan değişikliklerin başvurusu olarak kullanılabilir. Daha fazla bilgi için bkz Orleans . Sorun #8035 her örnekte yapılan değişiklikleri kategorilere ayırıyor.

Orleansglobal using Yönerge -leri

Tüm Orleans projeler doğrudan veya dolaylı olarak NuGet paketine başvurur Microsoft.Orleans.Sdk . Bir Orleans proje örtük kullanımları etkinleştirecekşekilde yapılandırıldığında (örneğin<ImplicitUsings>enable</ImplicitUsings>), Orleans ve Orleans.Hosting ad alanları örtük olarak kullanılır. Bu, uygulama kodunuzun bu yönergelere gerek duymadığı anlamına gelir.

Daha fazla bilgi için bkz . ImplicitUsings ve dotnet/orleans/src/Orleans. Sdk/derleme/Microsoft.Orleans. Sdk.targets.

Barındırma

türü ClientBuilder üzerinde IHostBuilderbir UseOrleansClient uzantı yöntemiyle değiştirilmiştir. Türü IHostBuilder Microsoft.Extensions.Hosting NuGet paketinden gelir. Bu, ayrı bir Orleans bağımlılık ekleme kapsayıcısı oluşturmak zorunda kalmadan mevcut bir konağa istemci ekleyebileceğiniz anlamına gelir. İstemci, başlatma sırasında kümeye bağlanır. İşlem tamamlandıktan sonra IHost.StartAsync istemci otomatik olarak bağlanır. öğesine IHostBuilder eklenen hizmetler kayıt sırasına göre başlatılır, bu nedenle aramadan ConfigureWebHostDefaults önce aramanın UseOrleansClient ASP.NET Core başlamadan önce başlatılmasını sağlarOrleans; örneğin, istemciye ASP.NET Core uygulamanızdan hemen erişmenizi sağlar.

Önceki ClientBuilder davranışı öykünmek isterseniz, ayrı HostBuilder bir oluşturup bunu bir Orleans istemciyle yapılandırabilirsiniz. IHostBuilder bir Orleans istemci veya Orleans silo yapılandırılabilir. Tüm silolar, uygulamasının kullanabileceği bir örneğini IGrainFactoryIClusterClient kaydeder, bu nedenle istemciyi ayrı olarak yapılandırmak gereksizdir ve desteklenmez.

OnActivateAsync ve OnDeactivateAsync imza değişikliği

Orleans , dilimlerin etkinleştirme ve devre dışı bırakma sırasında kod yürütmesine izin verir. Bu, depolama veya günlük yaşam döngüsü iletilerinden durum okuma gibi görevleri gerçekleştirmek için kullanılabilir. 7.0'da Orleans , bu yaşam döngüsü yöntemlerinin imzası değişti:

  • OnActivateAsync() şimdi bir CancellationToken parametre kabul eder. CancellationToken iptal edildiğinde etkinleştirme işlemi iptal edilmelidir.
  • OnDeactivateAsync() şimdi bir DeactivationReason parametre ve parametre CancellationToken kabul eder. , DeactivationReason etkinleştirmenin neden devre dışı bırakıldığını gösterir. Geliştiricilerin bu bilgileri günlüğe kaydetme ve tanılama amacıyla kullanması beklenir. CancellationToken iptal edildiğinde, devre dışı bırakma işlemi hemen tamamlanmalıdır. Herhangi bir konağın herhangi bir zamanda başarısız olabileceğinden, kritik durumu kalıcı hale getirme gibi önemli eylemleri gerçekleştirmek için kullanılması OnDeactivateAsync önerilmez.

Bu yeni yöntemleri geçersiz kılmaya yönelik aşağıdaki tahıl örneğini göz önünde bulundurun:

public sealed class PingGrain : Grain, IPingGrain
{
    private readonly ILogger<PingGrain> _logger;

    public PingGrain(ILogger<PingGrain> logger) =>
        _logger = logger;

    public override Task OnActivateAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("OnActivateAsync()");
        return Task.CompletedTask;
    }

    public override Task OnDeactivateAsync(DeactivationReason reason, CancellationToken token)
    {
        _logger.LogInformation("OnDeactivateAsync({Reason})", reason);
        return Task.CompletedTask;
    }

    public ValueTask Ping() => ValueTask.CompletedTask;
}

POCO Taneleri ve IGrainBase

içindeki Orleans taneciklerin artık temel sınıftan veya başka bir sınıftan Grain devralmalarına gerek yoktur. Bu işlev POCO tanecikleri olarak adlandırılır. Aşağıdakilerden herhangi biri gibi uzantı yöntemlerine erişmek için:

Tahılınızın uygulaması IGrainBase veya öğesinden Graindevralması gerekir. Aşağıda, bir taneli sınıf üzerinde uygulama IGrainBase örneği verilmiştir:

public sealed class PingGrain : IGrainBase, IPingGrain
{
    public PingGrain(IGrainContext context) => GrainContext = context;

    public IGrainContext GrainContext { get; }

    public ValueTask Ping() => ValueTask.CompletedTask;
}

IGrainBaseayrıca ve'yi OnDeactivateAsync varsayılan uygulamalarla tanımlayarakOnActivateAsync, isterseniz tahılınızın yaşam döngüsüne katılmasını sağlar:

public sealed class PingGrain : IGrainBase, IPingGrain
{
    private readonly ILogger<PingGrain> _logger;

    public PingGrain(IGrainContext context, ILogger<PingGrain> logger)
    {
        _logger = logger;
        GrainContext = context;
    }

    public IGrainContext GrainContext { get; }

    public Task OnActivateAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("OnActivateAsync()");
        return Task.CompletedTask;
    }

    public Task OnDeactivateAsync(DeactivationReason reason, CancellationToken token)
    {
        _logger.LogInformation("OnDeactivateAsync({Reason})", reason);
        return Task.CompletedTask;
    }

    public ValueTask Ping() => ValueTask.CompletedTask;
}

Serileştirme

7.0 sürümündeki Orleans en zahmetli değişiklik, sürüme dayanıklı seri hale getiricinin kullanıma sunulmasıdır. Bu değişiklik, uygulamaların gelişme eğiliminde olması nedeniyle yapılmıştır ve önceki seri hale getirici mevcut türlere özellik eklemeyi tolere edemediğinden geliştiriciler için önemli bir tuzak oluşturmıyordu. Öte yandan seri hale getirici esnektir ve geliştiricilerin genel türler, polimorfizm ve başvuru izleme gibi özellikler dahil olmak üzere çoğu .NET türünü değişiklik yapmadan temsil etmelerine olanak sağlar. Değiştirme süresi uzun sürdü, ancak kullanıcılar yine de türlerinin yüksek aslına uygunluk gösterimine ihtiyaç duyuyor. Bu nedenle, 7.0'da Orleans .NET türlerinin yüksek aslına uygunluk gösterimini desteklerken türlerin gelişmesine de izin veren bir değiştirme serileştiricisi kullanıma sunulmuştur. Yeni seri hale getirici önceki seri hale getiriciden çok daha verimlidir ve %170'e kadar daha yüksek uçtan uca aktarım hızı elde edilir.

Daha fazla bilgi için 7.0 ile ilgili olarak aşağıdaki makalelere Orleans bakın:

Tahıl kimlikleri

Tanelerin her biri, tahılın türünden ve anahtarından oluşan benzersiz bir kimliğe sahiptir. Önceki sürümleri, aşağıdakilerden Orleans birinin tanecik anahtarlarını desteklemek için s için GrainIdbileşik bir tür kullandı:

Bu, tahıl anahtarlarıyla ilgilenme konusunda biraz karmaşıklık içerir. Tahıl kimlikleri iki bileşenden oluşur: tür ve anahtar. Tür bileşeni daha önce sayısal tür kodu, kategori ve 3 bayt genel tür bilgilerinden oluşuyordu.

Tahıl kimlikleri artık hem hem de typekey dize olan formu type/key alır. En yaygın kullanılan tanecik anahtar arabirimidir IGrainWithStringKey. Bu, taneli kimliğin çalışma şeklini büyük ölçüde basitleştirir ve genel tane türleri desteğini geliştirir.

Hub'lı arabirimler artık karma kodun bir bileşimi ve herhangi bir genel tür parametresinin dize gösterimi yerine insan tarafından okunabilir bir ad kullanılarak da temsil edilir.

Yeni sistem daha özelleştirilebilir ve bu özelleştirmeler öznitelikler tarafından yönlendirilebilir.

  • GrainTypeAttribute(String) bir tanecik üzerinde, tanecik class kimliğinin Tür bölümünü belirtir.
  • DefaultGrainTypeAttribute(String)bir tanecik interface üzerinde, bir tanecik başvurusu alırken varsayılan olarak çözümlenmesi gereken tanenin IGrainFactory türünü belirtir. Örneğin, çağrılırkenIGrainFactory.GetGrain<IMyGrain>("my-key"), yukarıda belirtilen özniteliği belirtilmişseIMyGrain, tahıl fabrikası tahıla "my-type/my-key" bir başvuru döndürür.
  • GrainInterfaceTypeAttribute(String) arabirim adının geçersiz kılınmasına izin verir. Bu mekanizmayı kullanarak açıkça bir ad belirtmek, arabirim türünün mevcut tanecik başvurularıyla uyumluluğu bozmadan yeniden adlandırılmasına olanak tanır. Kimliği seri hale getirilebileceği için AliasAttribute arabiriminizde de bu durumda öğesinin olması gerektiğini unutmayın. Tür diğer adı belirtme hakkında daha fazla bilgi için serileştirme bölümüne bakın.

Yukarıda belirtildiği gibi, türleriniz için varsayılan tanecik sınıfını ve arabirim adlarını geçersiz kılmanız, mevcut dağıtımlarla uyumluluğu bozmadan temel türleri yeniden adlandırmanıza olanak tanır.

Akış kimlikleri

Akışlar ilk yayımlandığında Orleans , akışlar yalnızca kullanılarak Guidtanımlanabilir. Bu, bellek ayırma açısından verimliydi, ancak kullanıcıların belirli bir amaca uygun akış kimliğini belirlemek için genellikle bazı kodlama veya dolaylı işlemler gerektiren anlamlı akış kimlikleri oluşturması zordu.

7.0'da Orleans akışlar artık dizeler kullanılarak tanımlanır. üç Orleans.Runtime.StreamIdstruct özellik içerir: a StreamId.Namespace, a StreamId.Keyve .StreamId.FullKey Bu özellik değerleri UTF-8 dizeleri olarak kodlanmıştır. Örneğin, StreamId.Create(String, String).

SimpleMessage Akışlar'ın BroadcastChannel ile değiştirilmesi

SimpleMessageStreams (SMS olarak da adlandırılır) 7.0'da kaldırıldı. SMS ile aynı arabirime Orleans.Providers.Streams.PersistentStreamssahipti, ancak doğrudan taneli çağrılara bağlı olduğundan davranışı çok farklıydı. Karışıklığı önlemek için SMS kaldırıldı ve adlı Orleans.BroadcastChannel yeni bir değiştirme eklendi.

BroadcastChannel yalnızca örtük abonelikleri destekler ve bu durumda doğrudan bir değişim olabilir. Açık aboneliklere ihtiyacınız varsa veya arabirimi kullanmanız PersistentStream gerekiyorsa (örneğin, üretimde kullanırken testlerde SMS kullanıyordunuz EventHub ), MemoryStream sizin için en iyi adaydır.

BroadcastChannel , SMS ile aynı davranışlara sahip olurken MemoryStream diğer akış sağlayıcıları gibi davranır. Aşağıdaki Yayın Kanalı kullanım örneğini göz önünde bulundurun:

// Configuration
builder.AddBroadcastChannel(
    "my-provider",
    options => options.FireAndForgetDelivery = false);

// Publishing
var grainKey = Guid.NewGuid().ToString("N");
var channelId = ChannelId.Create("some-namespace", grainKey);
var stream = provider.GetChannelWriter<int>(channelId);

await stream.Publish(1);
await stream.Publish(2);
await stream.Publish(3);

// Simple implicit subscriber example
[ImplicitChannelSubscription]
public sealed class SimpleSubscriberGrain : Grain, ISubscriberGrain, IOnBroadcastChannelSubscribed
{
    // Called when a subscription is added to the grain
    public Task OnSubscribed(IBroadcastChannelSubscription streamSubscription)
    {
        streamSubscription.Attach<int>(
          item => OnPublished(streamSubscription.ChannelId, item),
          ex => OnError(streamSubscription.ChannelId, ex));

        return Task.CompletedTask;

        // Called when an item is published to the channel
        static Task OnPublished(ChannelId id, int item)
        {
            // Do something
            return Task.CompletedTask;
        }

        // Called when an error occurs
        static Task OnError(ChannelId id, Exception ex)
        {
            // Do something
            return Task.CompletedTask;
        }
    }
}

MemoryStream Yalnızca yapılandırmanın değiştirilmesi gerektiğinden geçiş daha kolay olacaktır. Aşağıdaki MemoryStream yapılandırmayı göz önünde bulundurun:

builder.AddMemoryStreams<DefaultMemoryMessageBodySerializer>(
    "in-mem-provider",
    _ =>
    {
        // Number of pulling agent to start.
        // DO NOT CHANGE this value once deployed, if you do rolling deployment
        _.ConfigurePartitioning(partitionCount: 8);
    });

OpenTelemetry

Telemetri sistemi 7.0'da Orleans güncelleştirildi ve önceki sistem ölçümler ve ActivitySource izleme için .NET Ölçümleri gibi standartlaştırılmış .NET API'leri yerine kaldırıldı.

Bunun bir parçası olarak, mevcut Microsoft.Orleans.TelemetryConsumers.* paketler kaldırıldı. Tarafından yayılan Orleans ölçümleri tercih edilen izleme çözümünüzle tümleştirme sürecini kolaylaştırmak için yeni bir paket kümesi eklemeyi düşünüyoruz. Her zaman olduğu gibi geri bildirim ve katkılar kabul edilir.

Araç, dotnet-counters geçici sistem durumu izleme ve birinci düzey performans araştırması için performans izleme özelliğine sahiptir. Sayaçlar için Orleans dotnet-counters aracı bunları izlemek için kullanılabilir:

dotnet counters monitor -n MyApp --counters Microsoft.Orleans

Benzer şekilde, OpenTelemetry ölçümleri aşağıdaki kodda gösterildiği gibi ölçümleri ekleyebilir Microsoft.Orleans :

builder.Services.AddOpenTelemetry()
    .WithMetrics(metrics => metrics
        .AddPrometheusExporter()
        .AddMeter("Microsoft.Orleans"));

Dağıtılmış izlemeyi etkinleştirmek için aşağıdaki kodda gösterildiği gibi OpenTelemetry'yi yapılandırabilirsiniz:

builder.Services.AddOpenTelemetry()
    .WithTracing(tracing =>
    {
        tracing.SetResourceBuilder(ResourceBuilder.CreateDefault()
            .AddService(serviceName: "ExampleService", serviceVersion: "1.0"));

        tracing.AddAspNetCoreInstrumentation();
        tracing.AddSource("Microsoft.Orleans.Runtime");
        tracing.AddSource("Microsoft.Orleans.Application");

        tracing.AddZipkinExporter(options =>
        {
            options.Endpoint = new Uri("http://localhost:9411/api/v2/spans");
        });
    });

Yukarıdaki kodda, OpenTelemetry aşağıdakileri izlemek üzere yapılandırılmıştır:

  • Microsoft.Orleans.Runtime
  • Microsoft.Orleans.Application

Etkinliği yaymak için çağrısı:AddActivityPropagation

builder.Host.UseOrleans((_, clientBuilder) =>
{
    clientBuilder.AddActivityPropagation();
});

Özellikleri çekirdek paketten ayrı paketlere yeniden düzenleme

7.0'da Orleans , uzantılarını kullanmayan Orleans.Coreayrı paketler halinde hesaba katmak için çaba sarf ettik. Yani, Orleans.Streaming, Orleans.Remindersve Orleans.Transactions çekirdekten ayrılmıştır. Bu, bu paketlerin kullandığınızkadar ödeme yaptığı ve çekirdekteki hiçbir kodun Orleans bu özelliklere adanmış olmadığı anlamına gelir. Bu işlem çekirdek API yüzeyini ve montaj boyutunu küçültür, çekirdeği basitleştirir ve performansı artırır. Performansla ilgili olarak, daha önce içindeki Orleans İşlemler, olası işlemleri koordine etmek için her yöntem için yürütülen bir kod gerektiriyordu. Bu, o zamandan beri her yönteme taşındı.

Bu, derlemeyi bozan bir değişikliktir. Daha önce temel sınıfta tanımlanmış Grain olan ancak artık uzantı yöntemleri olan yöntemlere çağrı yaparak anımsatıcılarla veya akışlarla etkileşim kuran mevcut kodunuz olabilir. Uzantı yöntemlerinin nitelenmesi gerektiğinden, belirtmeyen this bu tür çağrıların (GetRemindersörneğinthis.GetReminders()) dahil this edilecek şekilde güncelleştirilmesi gerekir. Bu çağrıları güncelleştirmezseniz bir derleme hatası oluşur ve nelerin değiştiğini bilmiyorsanız gerekli kod değişikliği belirgin olmayabilir.

İşlem istemcisi

Orleans7.0, işlemleri koordine etmek için yeni bir soyutlama ekler. Orleans.ITransactionClient Daha önce işlemler yalnızca taneciklerle koordine edilebiliyor. bağımlılık ekleme yoluyla kullanılabilen ile ITransactionClient, istemciler bir aracı tanesine gerek kalmadan işlemleri de koordine edebilir. Aşağıdaki örnek, kredileri bir hesaptan çeker ve tek bir işlem içinde başka bir hesapta depolar. Bu kod, bir tanecik içinden veya bağımlılık ekleme kapsayıcısından öğesini alan ITransactionClient bir dış istemciden çağrılabilir.

await transactionClient.RunTransaction(
  TransactionOption.Create,
  () => Task.WhenAll(from.Withdraw(100), to.Deposit(100)));

İstemci tarafından koordine edilen işlemler için, istemcinin yapılandırma sırasında gerekli hizmetleri eklemesi gerekir:

clientBuilder.UseTransactions();

BankAccount örneği, kullanımını ITransactionClientgösterir. Daha fazla bilgi için bkz Orleans . işlemler.

Çağrı zinciri yeniden giriş

Tanecikler tek iş parçacıklıdır ve istekleri varsayılan olarak baştan tamamlamaya kadar tek tek işler. Başka bir deyişle, tahıllar varsayılan olarak yeniden giriş yapılmaz. öğesinin ReentrantAttribute bir taneli sınıfa eklenmesi, tek iş parçacıklı olarak birden çok isteğin eşzamanlı olarak, birbirine bağlanarak işlenmesini sağlar. Bu, iç durumu olmayan veya HTTP çağrıları verme veya veritabanına yazma gibi çok sayıda zaman uyumsuz işlem gerçekleştiren tanecikler için yararlı olabilir. İstekler bir araya geldiğinde ek özen gösterilmesi gerekir: Zaman uyumsuz işlem tamamlanıp yöntem yürütmeyi sürdürürken bir await deyimin değişmeden önce bir tanecik durumunun gözlemlenmesi mümkündür.

Örneğin, aşağıdaki dilim bir sayacı temsil eder. birden çok çağrının araya katmasına izin veren olarak işaretlendi Reentrant. yöntemi iç Increment() sayacı artırmalı ve gözlemlenen değeri döndürmelidir. Ancak, yöntem gövdesi bir await noktadan önce tahılın durumunu gözlemlediğinden Increment() ve daha sonra güncelleştirdiğinden, birden çok araya ekleme yürütmesinin Increment() alınan toplam çağrı sayısından Increment() daha az olmasına _value neden olabilir. Bu, yanlış yeniden giriş kullanımından kaynaklanan bir hatadır.

öğesini kaldırmak ReentrantAttribute sorunu çözmek için yeterlidir.

[Reentrant]
public sealed class CounterGrain : Grain, ICounterGrain
{
    int _value;
    
    /// <summary>
    /// Increments the grain's value and returns the previous value.
    /// </summary>
    public Task<int> Increment()
    {
        // Do not copy this code, it contains an error.
        var currentVal = _value;
        await Task.Delay(TimeSpan.FromMilliseconds(1_000));
        _value = currentVal + 1;
        return currentValue;
    }
}

Bu tür hataları önlemek için, tanecikler varsayılan olarak yeniden giriş yapmaz. Bunun dezavantajı, uygulamalarında zaman uyumsuz işlemler gerçekleştiren tanecikler için aktarım hızını azaltır çünkü diğer istekler, zaman uyumsuz işlemin tamamlanmasını beklerken işlenemez. Bunu hafifletmek için, Orleans belirli durumlarda yeniden girişe izin vermek için çeşitli seçenekler sunar:

  • Sınıfın tamamı için: öğesinin grene ReentrantAttribute yerleştirilmesi, diğer isteklerle araya eklemek için tahıla yönelik herhangi bir isteğin yapılmasına olanak tanır.
  • Yöntemlerin bir alt kümesi için: grain arabirimi yöntemine AlwaysInterleaveAttribute yerleştirmek, bu yönteme yönelik isteklerin diğer isteklerle birlikte çalışmasına ve bu yönteme yönelik isteklerin başka bir istek tarafından araya alınmasına olanak tanır.
  • Yöntemlerin bir alt kümesi için: grain arabirimi yöntemine ReadOnlyAttribute yerleştirmek, bu yönteme yönelik isteklerin diğer ReadOnly isteklerle birlikte çalışmasına ve bu yönteme yönelik isteklerin başka ReadOnly bir istek tarafından araya alınmasına olanak tanır. Bu anlamda, daha kısıtlı bir biçimidir AlwaysInterleave.
  • Çağrı zinciri içindeki tüm istekler için: RequestContext.AllowCallChainReentrancy() ve <xref:Orleans. Runtime.RequestContext.SuppressCallChainReentrancy?displayProperty=nameWithType, aşağı akış isteklerinin tahıla yeniden girme izni verme işleminin kabul edilmesini ve devre dışı bırakılmasını sağlar. Her iki çağrı da istekten çıkarken atılması gereken bir değer döndürür. Bu nedenle, uygun kullanım aşağıdaki gibidir:
public Task<int> OuterCall(IMyGrain other)
{
    // Allow call-chain reentrancy for this grain, for the duration of the method.
    using var _ = RequestContext.AllowCallChainReentrancy();
    await other.CallMeBack(this.AsReference<IMyGrain>());
}

public Task CallMeBack(IMyGrain grain)
{
    // Because OuterCall allowed reentrancy back into that grain, this method 
    // will be able to call grain.InnerCall() without deadlocking.
    await grain.InnerCall();
}

public Task InnerCall() => Task.CompletedTask;

Çağrı zinciri yeniden giriş, dilim başına, çağrı zinciri başına kabul edilmelidir. Örneğin, A ve B taneleri olmak üzere iki taneyi göz önünde bulundurun. Grain A, B tanesini çağırmadan önce çağrı zincirinin yeniden girişine olanak sağlıyorsa, B tanesi bu çağrıda A tanesine geri çağrı yapabilir. Ancak, B taneli B de çağrı zinciri yeniden giriş özelliğini etkinleştirmediyse, A dilimi B tanesine geri çağrı yapamaz. Her bir tanecik, çağrı zinciri başınadır.

Tanecikler ayrıca çağrı zinciri yeniden giriş bilgilerini kullanarak using var _ = RequestContext.SuppressCallChainReentrancy()bir çağrı zincirinin aşağı akmasını engelleyebilir. Bu, sonraki çağrıların yeniden girmesini engeller.

Geçiş betiklerini ADO.NET

ADO.NET kullanan kümeleme, kalıcılık ve anımsatıcılarla ileriye dönük uyumluluğu Orleans sağlamak için uygun SQL geçiş betiğine ihtiyacınız vardır:

Kullanılan veritabanı için dosyaları seçin ve sırayla uygulayın.