Orleans 7.0에는 호스팅 개선, 사용자 지정 직렬화, 불변성, 조직 추상화를 비롯한 몇 가지 유용한 변경이 도입되었습니다.
마이그레이션
Orleans이 곡물과 스트림을 식별하는 방식에 변화가 있어, 미리 알림, 스트림, 또는 곡물 지속성을 사용하는 기존 애플리케이션을 Orleans 7.0으로 마이그레이션하는 것이 현재 쉽지 않습니다.
롤링 업그레이드를 통해 이전 Orleans 버전을 실행하는 애플리케이션을 7.0으로 원활하게 업그레이드할 Orleans 수 없습니다. 따라서 새 클러스터 배포 및 이전 클러스터 서비스 해제와 같은 다른 업그레이드 전략을 사용합니다. Orleans7.0은 유선 프로토콜을 호환되지 않게 변경합니다. 즉, 클러스터에는 이전 Orleans 버전을 실행하는 호스트와 Orleans7.0 호스트를 혼합하여 포함할 수 없습니다.
주요 릴리스에서도 이러한 호환성이 손상되는 변경은 수년 동안 방지되었습니다. 지금이어야 하는 이유는 무엇인가요? 정체성과 serialization이라는 두 가지 주요 이유가 있습니다. ID와 관련하여, 현재 그레인 및 스트림 ID는 문자열로 구성됩니다. 이렇게 하면 곡물이 제네릭 형식 정보를 제대로 인코딩할 수 있으며 스트림을 애플리케이션 도메인에 더 쉽게 매핑할 수 있습니다. 이전에는 Orleans가 제네릭 곡물을 나타낼 수 없는 복잡한 데이터 구조를 사용하여 곡물 유형을 식별함으로써 예외 상황을 초래했습니다. 스트림은 string 네임스페이스와 Guid 키를 사용하여 식별되었으며 이는 효율적이지만 애플리케이션 도메인에 매핑하기 어려웠습니다. 이제 직렬화는 버전에 관대합니다. 즉, 직렬화 오류 없이 애플리케이션을 업그레이드할 수 있다는 확신을 가지고 규칙 집합에 따라 호환되는 특정 방식으로 형식을 수정할 수 있습니다. 이 기능은 애플리케이션 유형이 스트림 또는 곡물 스토리지에 유지되는 경우에 특히 유용합니다. 다음 섹션에서는 주요 변경사항을 설명하고 이에 대해 더 깊이 있게 논의합니다.
패키징 변경
프로젝트를 7.0으로 업그레이드할 Orleans 때 다음 작업을 수행합니다.
- 모든 클라이언트는 Microsoft.Orleans.Client를 참조해야 합니다.
- 모든 사일로(서버)는 Microsoft.Orleans.Server를 참조해야 합니다.
- 다른 모든 패키지는 Microsoft.Orleans.Sdk를 참조해야 합니다.
- 클라이언트 및 서버 패키지에는 모두 Microsoft.Orleans.Sdk에 대한 참조가 포함되어 있습니다.
-
Microsoft.Orleans.CodeGenerator.MSBuild및Microsoft.Orleans.OrleansCodeGenerator.Build에 대한 모든 참조를 제거합니다.-
KnownAssembly의 사용을 GenerateCodeForDeclaringAssemblyAttribute로 바꿉니다. -
Microsoft.Orleans.Sdk패키지는 C# 원본 생성기 패키지(Microsoft.Orleans.CodeGenerator)를 참조합니다.
-
-
Microsoft.Orleans.OrleansRuntime에 대한 모든 참조를 제거합니다.-
Microsoft.Orleans.Server 패키지는 그 대체품인
Microsoft.Orleans.Runtime를 참조합니다.
-
Microsoft.Orleans.Server 패키지는 그 대체품인
-
ConfigureApplicationParts호출을 제거합니다. 애플리케이션 파트 가 제거되었습니다. C# 원본 생성기는 모든 패키지(클라이언트 및 서버 포함)에 Orleans 추가되고 해당 애플리케이션 파트를 자동으로 생성합니다. -
Microsoft.Orleans.OrleansServiceBus대한 참조를 Microsoft로 대체합니다.Orleans. Streaming.EventHubs. - 미리 알림을 사용하는 경우 Microsoft에 대한 참조를 추가합니다Orleans. 미리 알림.
- 스트림을 사용하는 경우 Microsoft에Orleans 대한 참조를 추가합니다. 스트리밍.
팁
모든 Orleans 샘플은 Orleans 7.0으로 업그레이드되었으며 변경 내용에 대한 참조로 사용할 수 있습니다. 자세한 내용은 각 샘플에 대한 변경 내용을 항목화하는 Orleans 문제 #8035를 참조하세요.
Orleans global using 지시문
모든 Orleans 프로젝트는 Microsoft.Orleans.Sdk NuGet 패키지를 직접 또는 간접적으로 참조합니다.
Orleans 프로젝트가 암시적 사용을 활성화하도록 구성된 경우(예:<ImplicitUsings>enable</ImplicitUsings>), 프로젝트는 암시적으로 Orleans 및 Orleans.Hosting 네임스페이스를 모두 사용합니다. 즉, 앱 코드에는 이러한 using 지시문이 필요하지 않습니다.
자세한 내용은 ImplicitUsings 및 dotnet/orleans/src/Orleans.Sdk/build/Microsoft.Orleans.Sdk.targets를 참조하세요.
호스팅
ClientBuilder 유형이 UseOrleansClient의 IHostBuilder 확장 메서드로 대체됩니다.
IHostBuilder 형식은 Microsoft.Extensions.Hosting NuGet 패키지에서 가져옵니다. 즉 Orleans , 별도의 종속성 주입 컨테이너를 만들지 않고 클라이언트를 기존 호스트에 추가할 수 있습니다. 클라이언트는 시작하는 동안 클러스터에 연결합니다. 완료되면 IHost.StartAsync 클라이언트가 자동으로 연결됩니다. 등록 순서대로 IHostBuilder 시작 부분에 추가된 서비스입니다. 예를 들어 UseOrleansClient를 호출한 후 ConfigureWebHostDefaults를 호출하면 Orleans가 ASP.NET Core가 시작되기 전에 시작되어, ASP.NET Core 애플리케이션에서 클라이언트에 즉시 액세스할 수 있습니다.
이전 ClientBuilder 동작을 에뮬레이트하려면 별도의 HostBuilder 동작을 만들고 클라이언트를 사용하여 Orleans 구성합니다.
IHostBuilder는 Orleans 클라이언트 또는 Orleans 사일로로 구성할 수 있습니다. 모든 사일로는 애플리케이션에서 사용할 수 있는 IGrainFactory 및 IClusterClient의 인스턴스를 등록하므로 클라이언트를 별도로 구성하는 것은 불필요하며 지원되지 않습니다.
OnActivateAsync 및 OnDeactivateAsync 서명 변경
Orleans는 활성화 및 비활성화 중에 그레인이 코드를 실행할 수 있도록 허용합니다. 이 기능을 사용하여 스토리지에서 상태 읽기 또는 수명 주기 메시지 로깅과 같은 작업을 수행할 수 있습니다. Orleans 7.0에서는 이러한 수명 주기 메서드의 서명이 변경되었습니다.
- OnActivateAsync()는 이제 CancellationToken 매개 변수를 허용합니다. CancellationToken 취소되면 활성화 프로세스를 중단합니다.
-
OnDeactivateAsync()는 이제 DeactivationReason 매개 변수 및
CancellationToken매개 변수를 허용합니다.DeactivationReason은 활성화가 비활성화되는 이유를 나타냅니다. 로깅 및 진단 목적으로 이 정보를 사용합니다.CancellationToken취소되면 즉시 비활성화 프로세스를 완료합니다. 언제든지 모든 호스트가 실패할 수 있으므로 중요한 상태 유지와 같은 중요한 작업을 수행하는 데 의존하는OnDeactivateAsync것은 권장되지 않습니다.
이러한 새로운 메서드를 오버라이드하는 곡물의 다음 예제를 고려해보겠습니다.
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 곡물 및 IGrainBase
Orleans의 grains는 더 이상 Grain 기본 클래스 또는 다른 클래스에서 상속할 필요가 없습니다. 이 기능을 POCO 그레인이라고 합니다. 다음과 같은 확장 메서드에 액세스하려면 다음을 수행합니다.
- DeactivateOnIdle
- AsReference
- Cast
- GetPrimaryKey
- GetReminder
- GetReminders
- RegisterOrUpdateReminder
- UnregisterReminder
- GetStreamProvider
그레인은 IGrainBase을 구현하거나 Grain에서 상속되어야 합니다. 다음은 그레인 클래스에서 구현하는 IGrainBase 예입니다.
public sealed class PingGrain : IGrainBase, IPingGrain
{
public PingGrain(IGrainContext context) => GrainContext = context;
public IGrainContext GrainContext { get; }
public ValueTask Ping() => ValueTask.CompletedTask;
}
IGrainBase 또한 기본 구현을 통해 OnActivateAsync 및 OnDeactivateAsync를 정의하여, 곡물이 원하는 경우 수명 주기에 참여할 수 있도록 합니다.
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;
}
직렬화
Orleans 7.0에서 가장 부담스러운 변화는 버전에 유연한 직렬 변환기의 도입입니다. 이러한 변경은 애플리케이션이 발전하는 경향이 있기 때문에 발생했으며, 이전 직렬 변환기는 기존 형식에 속성을 추가하는 것을 허용할 수 없었기 때문에 개발자에게 상당한 어려움을 초래했습니다. 반면에 이전 직렬 변환기는 유연하여 제네릭, 다형성 및 참조 추적과 같은 기능을 포함하여 대부분의 .NET 형식을 수정하지 않고 표시할 수 있었습니다. 교체는 오래 기한이 지났지만 형식의 충실도가 높은 표현은 여전히 필요합니다. 따라서 Orleans 7.0에서는 .NET 형식의 충실도 표현을 지원하는 대체 직렬 변환기를 도입하는 동시에 형식이 발전할 수 있도록 합니다. 새 직렬 변환기는 이전 직렬 변환기보다 훨씬 효율적이므로 엔드투엔드 처리량이 최대 170% 더 높습니다.
자세한 내용은 Orleans 7.0과 관련된 다음 문서를 참조하세요.
곡물 정체성
곡물은 각각 곡물의 유형과 해당 키로 구성된 고유한 ID를 갖습니다. 이전 Orleans 버전에서는 다음 중 하나의 곡물 키를 지원하기 위해 GrainId복합 형식을 사용했습니다.
이 방법은 곡물 키를 처리할 때 약간 복잡합니다. 그레인 ID는 유형과 키라는 두 가지 구성 요소로 구성됩니다. 형식 구성 요소는 이전에 숫자 형식 코드, 범주 및 3바이트의 제네릭 형식 정보로 구성되었습니다.
이제 곡물 ID는 형식 type/key을 사용하며, type과 key는 모두 문자열입니다. 가장 일반적으로 사용되는 곡물 키 인터페이스는 IGrainWithStringKey. 이렇게 하면 그레인 식별자의 작동 방식이 크게 간소화되고 제네릭 그레인 유형에 대한 지원이 향상됩니다.
이제 곡물 인터페이스는 해시 코드와 제네릭 형식 매개 변수의 문자열 표현의 조합이 아니라 사람이 읽을 수 있는 이름을 사용하여 표시됩니다.
새 시스템은 사용자 지정할 수 있으며 이러한 사용자 지정은 특성으로 구동할 수 있습니다.
-
GrainTypeAttribute(String) 는 그레인
classID의 형식 부분을 지정합니다. -
DefaultGrainTypeAttribute(String)는 곡물
interface참조를 받을 때 기본적으로 확인해야 하는 곡물의 IGrainFactory을 지정합니다. 예를 들어,IGrainFactory.GetGrain<IMyGrain>("my-key")를 호출할 때,"my-type/my-key"에 앞서 언급한 속성이 지정되어 있는 경우, 그레인 팩토리는 그레인IMyGrain에 대한 참조를 반환합니다. - GrainInterfaceTypeAttribute(String)는 인터페이스 이름을 재정의할 수 있도록 허용합니다. 이 메커니즘을 사용하여 명시적으로 이름을 지정하면 기존 곡물 참조와의 호환성을 손상하지 않고 인터페이스 형식의 이름을 바꿈할 수 있습니다. 이 경우 인터페이스는 ID가 serialize될 수 있으므로 AliasAttribute를 포함해야 합니다. 형식 별칭을 지정하는 방법에 대한 자세한 내용은 serialization 관련 섹션을 참조하세요.
위에서 설명한 것처럼 형식에 대한 기본 곡물 클래스 및 인터페이스 이름을 재정의하면 기존 배포와의 호환성을 손상하지 않고 기본 형식의 이름을 바꿈할 수 있습니다.
스트림 ID
Orleans 스트림이 처음 릴리스되었을 때 스트림은 Guid를 사용해야만 식별할 수 있었습니다. 이 방법은 메모리 할당 측면에서 효율적이지만 의미 있는 스트림 ID를 만들기가 어려웠으며, 특정 목적을 위해 적절한 스트림 ID를 결정하기 위해 일부 인코딩 또는 간접 참조가 필요한 경우가 많습니다.
7.0에서 Orleans 스트림은 문자열을 사용하여 식별됩니다. 에는 Orleans.Runtime.StreamIdstruct 세 가지 StreamId.Namespace속성이 StreamId.KeyStreamId.FullKey포함됩니다. 이러한 속성 값은 인코딩된 UTF-8 문자열입니다. 예를 들어 StreamId.Create(String, String)를 참조하세요.
SimpleMessageStreams를 BroadcastChannel로 대체
SimpleMessageStreams (SMS라고도 함)는 7.0에서 제거됩니다. SMS는 Orleans.Providers.Streams.PersistentStreams와 동일한 인터페이스를 가지고 있었지만, 직접 데이터 유닛 간 호출에 의존했기 때문에 동작 방식이 매우 달랐습니다. 혼동을 방지하기 위해 SMS가 제거되고 새로운 교체가 Orleans.BroadcastChannel 도입되었습니다.
BroadcastChannel은 암시적 구독만 지원하며 이 경우 직접 대체될 수 있습니다. 명시적 구독이 필요하거나 인터페이스를 PersistentStream 사용해야 하는 경우(예: 프로덕션에서 사용된 동안 EventHub 테스트에서 SMS가 사용된 경우) MemoryStream 가장 적합한 후보입니다.
BroadcastChannel 에는 SMS와 동일한 동작이 있지만 MemoryStream 다른 스트림 공급자처럼 동작합니다. 다음 브로드캐스트 채널 사용 예제를 고려해 보세요.
// 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 마이그레이션이 더 쉽습니다. 다음 MemoryStream 구성을 고려해 보세요.
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
원격 분석 시스템은 7.0에서 Orleans 업데이트되고 이전 시스템은 메트릭 및 추적에 대한 .NET 메트릭과 같은 표준화된 .NET API를 위해 제거됩니다 ActivitySource .
이 작업의 일부로 기존 Microsoft.Orleans.TelemetryConsumers.* 패키지가 제거됩니다. 선택한 모니터링 솔루션에 메트릭 통합을 간소화하기 위해 Orleans에서 내보내는 새로운 패키지 집합이 고려되고 있습니다. 항상 그런 것처럼 피드백과 기여도 환영합니다.
dotnet-counters 도구는 임시 상태 모니터링 및 1단계 수준 성능 조사를 위한 성능 모니터링 기능을 제공합니다. 카운터의 경우 Orleansdotnet-counters 도구를 사용하여 모니터링합니다.
dotnet counters monitor -n MyApp --counters Microsoft.Orleans
마찬가지로 다음 코드에 표시된 대로 Microsoft.Orleans 미터를 OpenTelemetry 메트릭에 추가합니다.
builder.Services.AddOpenTelemetry()
.WithMetrics(metrics => metrics
.AddPrometheusExporter()
.AddMeter("Microsoft.Orleans"));
분산 추적을 사용하도록 설정하려면 다음 코드와 같이 OpenTelemetry를 구성합니다.
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");
});
});
앞의 코드에서 OpenTelemetry는 다음을 모니터링하도록 구성됩니다.
Microsoft.Orleans.RuntimeMicrosoft.Orleans.Application
활동을 전파하려면 AddActivityPropagation을 호출합니다.
builder.Host.UseOrleans((_, clientBuilder) =>
{
clientBuilder.AddActivityPropagation();
});
핵심 패키지의 기능을 별도의 패키지로 리팩터링
7.0에서 Orleans 확장들은 Orleans.Core에 의존하지 않는 별도의 패키지로 분리되었습니다. 즉, Orleans.Streaming, 및 Orleans.RemindersOrleans.Transactions 코어에서 분리되었습니다. 즉, 이러한 패키지는 사용된 항목에 대해 전적으로 비용을 지불하며 코어의 Orleans 코드는 이러한 기능에만 해당되지 않습니다. 이 방법은 코어 API 표면과 어셈블리 크기를 줄이며 코어를 간소화하고 성능을 향상시킵니다. 성능과 관련하여 이전에 트랜잭션에는 Orleans 잠재적인 트랜잭션을 조정하기 위해 모든 메서드에 대해 실행되는 일부 코드가 필요했습니다. 이 조정 논리는 이제 메서드별로 이동됩니다.
이것은 컴파일 호환성이 손상되는 변경입니다. 기본 클래스에 Grain 이전에 정의된 메서드를 호출하여 미리 알림 또는 스트림과 상호 작용하는 기존 코드는 이제 확장 메서드이므로 중단될 수 있습니다.
this을 지정하지 않은 호출(예: GetReminders)을 업데이트하여 this을 포함시키십시오(예: this.GetReminders()). 확장 메서드는 반드시 명시적으로 지정되어야 합니다. 이러한 호출이 업데이트되지 않은 경우 컴파일 오류가 발생하며, 변경된 내용을 모르면 필요한 코드 변경이 명확하지 않을 수 있습니다.
트랜잭션 클라이언트
Orleans7.0에서는 트랜잭션을 조정하기 위한 새로운 추상화가 도입되었습니다. Orleans.ITransactionClient 이전에는 곡물만 트랜잭션을 조정할 수 있습니다. 종속성 주입을 통해 사용할 수 있는 ITransactionClient가 있으면, 클라이언트는 중간 매개체 없이도 트랜잭션을 조정할 수 있습니다. 다음 예제에서는 한 계정에서 크레딧을 인출하고 단일 트랜잭션 내의 다른 계정에 입금합니다. 그레인 내에서 또는 종속성 주입 컨테이너에서 ITransactionClient를 검색한 외부 클라이언트에서 이 코드를 호출합니다.
await transactionClient.RunTransaction(
TransactionOption.Create,
() => Task.WhenAll(from.Withdraw(100), to.Deposit(100)));
클라이언트가 조정하는 트랜잭션의 경우 클라이언트는 구성 중에 필요한 서비스를 추가해야 합니다.
clientBuilder.UseTransactions();
BankAccount 샘플은 ITransactionClient의 사용을 보여 줍니다. 자세한 내용은 Orleans 거래를 참조하세요.
호출 체인 재진입
그레인은 단일 스레드로 작동하며, 기본적으로 요청을 처음부터 완료할 때까지 하나씩 처리합니다. 즉, 그레인은 기본적으로 재진입할 수 없습니다.
ReentrantAttribute를 그레인 클래스에 추가하면 단일 스레드 작동을 유지하면서도 인터리빙 방식으로 여러 요청을 동시에 처리할 수 있습니다. 이 기능은 내부 상태를 유지하지 않거나 HTTP 호출을 실행하거나 데이터베이스에 쓰는 것과 같은 많은 비동기 작업을 수행하는 데 유용할 수 있습니다. 요청이 인터리브될 수 있는 경우, 추가적인 주의가 필요합니다. 비동기 작업이 완료되고 메서드가 실행을 재개할 때까지 await 문 이전에 관찰된 곡물의 상태가 변경될 수 있습니다.
예를 들어 다음 곡물은 카운터를 나타냅니다. 여러 번 호출하여 인터리브할 수 있도록 Reentrant으로 표시되어 있습니다.
Increment() 메서드는 내부 카운터를 증가시키고 관찰된 값을 반환해야 합니다. 그러나 메서드 본문은 Increment() 지점 이전 await 의 곡물 상태를 관찰하고 나중에 업데이트하기 때문에 여러 인터리브 실행을 Increment() 수행하면 _value 수신된 총 호출 수 Increment() 보다 작을 수 있습니다. 이것은 재진입의 잘못된 사용으로 인해 발생하는 오류입니다.
ReentrantAttribute를 삭제하면 이 문제를 해결하기에 충분합니다.
[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;
}
}
이러한 오류를 방지하기 위해 곡물은 기본적으로 재진입할 수 없습니다. 비동기 작업이 완료되기를 기다리는 동안 그레인이 다른 요청을 처리할 수 없으므로 구현에서 비동기 작업을 수행하는 곡물의 처리량이 줄어듭니다. 이를 완화하기 위해 Orleans는 특정 경우에 재진입을 허용하는 몇 가지 옵션을 제공합니다.
- 전체 클래스에 대해: ReentrantAttribute를 그레인에 배치하면 그레인에 대한 모든 요청이 다른 요청과 교차할 수 있습니다.
- 메서드 하위 집합의 경우: AlwaysInterleaveAttribute을 그레인 인터페이스 메서드에 배치하면 해당 메서드로의 요청이 다른 모든 요청과 인터리브될 수 있으며, 다른 요청도 해당 메서드로의 요청과 인터리브될 수 있습니다.
- 메서드 하위 집합의 경우: 그레인 ReadOnlyAttribute 메서드에 를 배치하면 해당 메서드의 요청이 다른
ReadOnly요청과 혼합되어 처리될 수 있으며, 다른ReadOnly요청이 해당 메서드의 요청과 혼합되어 처리될 수 있습니다. 이런 의미에서 더 제한된 형식입니다AlwaysInterleave. - 호출 체인 내의 모든 요청의 경우: RequestContext.AllowCallChainReentrancy()와 RequestContext.SuppressCallChainReentrancy()는 다운스트림 요청이 'grain'을 다시 입력할 수 있도록 허용하거나 허용하지 않는 옵션을 제공합니다. 두 호출 모두 요청을 종료할 때 삭제 해야 하는 값을 반환합니다. 따라서 다음과 같이 사용합니다.
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와 B라는 두 가지 곡물을 고려해 보세요. grain A가 그레인 B를 호출하기 전에 호출 체인 재진입을 사용하도록 설정하면 grain B는 해당 호출에서 grain A로 다시 호출할 수 있습니다. grain B가 호출 체인 재진입을 또한 설정하지 않으면 grain A는 grain B로 다시 호출할 수 없습니다. 각 그레인 및 통화 체인별로 사용하도록 설정됩니다.
그레인은 using var _ = RequestContext.SuppressCallChainReentrancy()를 사용하여 호출 체인 재진입 정보를 억제하여 호출 체인 아래로 전파되지 않도록 할 수 있습니다. 이렇게 하면 후속 호출이 재진입되지 않습니다.
ADO.NET 마이그레이션 스크립트
ADO.NET 사용하는 클러스터링, 지속성 및 미리 알림과의 Orleans 호환성을 보장하기 위해 적절한 SQL 마이그레이션 스크립트가 필요합니다.
사용된 데이터베이스의 파일을 선택하고 순서대로 적용합니다.
.NET