Bot releases are visible (Hide)
!Activation Repartitioning in action
Above: a demonstration showing Activation Repartitioning in action. The red lines represent cross-silo communication. As the red lines are eliminated by the partitioning algorithm, throughput improves to over 2x the initial throughput.
Ledjon Behluli and @ReubenBond implemented activation repartitioning in #8877. When enabled, activation repartitioning collocates grains based on observed communication patterns to improve performance while keeping load balanced across your cluster. In initial benchmarks, we observe throughput improvements in the range of 30% to 110%. The following paragraphs provide more background and implementation details for those who are interested. The feature is currently experimental and to enable it you need to opt-in on every silo in your cluster using the ISiloBuilder.AddActivationRepartitioner()
extension method, suppressing the experimental feature warning:
#pragma warning disable ORLEANSEXP001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
siloBuilder.AddActivationRepartitioner();
#pragma warning restore ORLEANSEXP001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
The fastest and cheapest grains calls are ones which don't cross process boundaries. These grain calls do not need to be serialized and do not need to incur network transmission costs. For that reason, collocating related grains within the same host can significantly improve the performance of your application. On the other hand, if all grains were placed in a single host, that host may become overloaded and crash, and you would not be able to scale your application across multiple hosts. How can we maximize collocation of related grains while keeping load across your hosts balanced? Before describing our solution, we need to provide some background.
Grain placement in Orleans is flexible: Orleans executes a user-defined function when deciding where in a cluster to place each grain, providing your function with a list of the compatible silos in your cluster, that is, the silos which support the grain type and interface version which triggered placement. Grains calls are location-transparent, so callers do not need to know where a grain is located, allowing grains to be placed anywhere across your cluster of hosts. Each grain's current location is stored in a distributed directory and lookups to the directory are cached for performance.
Resource-optimized placement was implemented by @ledjon-behluli in #8815. Resource-optimized placement uses runtime statistics such as total and available memory, CPU usage, and grain count, collected from all hosts in the cluster, smooths them, and combines them to calculate a load score. It selects the least-loaded silo from a subset of hosts to balance load evenly across the cluster[^4]. If the load score of the local silo is within some configured range of the best candidate's load score, the local silo is chosen preferentially. This improves grain locality by leveraging the knowledge that the local silo initiated a call to the grain and therefore has some relation to that grain.
Ledjon wrote more about Resource-optimized placement in this blog post.
Originally, there was no straightforward way to move an active grain from one host to another without needing to fully deactivate the grain, unregister it from the grain directory, contend with concurrent callers on where to place the new activation, and reload its state from the database when the new activation is created. Live grain migration was introduced in #8452, allowing grains to transparently migrate from one silo to another on-demand without needing to reload state from the database, and without affecting pending requests. Live grain migration introduced two new lifecycle stages: dehydration and rehydration. The grain's in-memory state (application state, enqueued messages, metadata) is dehydrated into a migration packet which is sent to the destination silo where it's rehydrated. Live grain migration provided the mechanism for grains to migrate across hosts, but did not provide any out-of-the-box policies to automate migration. Users trigger grain migration by calling this.MigrateOnIdle()
from within a grain, optionally providing a placement hint which the grain's configured placement director can use to select a destination host for the grain activation.
Finally, we have the pieces in place for activation repartitioning: grain activations are load-balanced across the cluster, and they are able to migrate from host to host quickly. While live grain migration gives developers a mechanism to migrate grain activations from one host to another, it does not provide any automated policy to do so. Remember, we want grains to be balanced across the cluster and collocated with related grains to reduce networking and serialization cost. This is a difficult challenge since:
Folks at Microsoft Research studied this problem and proposed a solution in a paper titled Optimizing Distributed Actor Systems for Dynamic Interactive Services. The paper, dubbed ActOp, proposes a decentralized approximate solution which achieves good results in their benchmarks. Their implementation was never merged into Orleans and we were unable to find the original implementation on Microsoft's internal network. So, after first implementing resource-optimized placement, community contributor @ledjon-behluli set out to implement activation repartitioning from scratch based on the ActOp paper. The following paragraphs describe the algorithm and the enhancements we made along the way.
The activation repartitioning algorithm involves pair-wise exchange of grains between two hosts at a time. Silos compute a candidate set of grains to send to a peer, then the peer does similarly, and uses a greedy algorithm to determine a final exchange set which minimizes cost while keeping silos balanced.
To compute the candidate sets, silos track which grains communicate with which other grains and how frequently. The whole graph would be unwieldy, so we only maintain the top-K communication edges using a variant of the Space-Saving[^1] algorithm. Messages are sampled via a multi-producer, single consumer ring buffer which drops messages if the partition is full. They are then processed by a single thread, which yields frequently to give other threads CPU time. When the distribution has low skew and the K parameter is fairly small, Space-Saving can require a lot of costly shuffling at the bottom of its max-heap (we use the heap variant to reduce memory). To address this, we use Filtered Space-Saving[^2] instead of Space-Saving. Filtered Space-Saving involves putting a 'sketch' data structure at the bottom of the max heap for the lower end of the distribution, which can greatly reduce churn at the bottom and improve performance by up to ~2x in our tests.
If the top-K communication edges are all internal (eg, because the algorithm has already optimized partitioning somewhat), silos won't find many good transfer candidates. We need to track internal edges to work out which grains should/shouldn't be transferred (cost vs benefit). To address this, we introduced a bloom filter to track grains where the cost of movement is greater than the benefit, removing them from the top-K data structure. From our experiments, this works very well with even a 10x smaller K. This performance improvement will come with a reduced ability to handle dynamic graphs, so in the future we may need to implement a decay strategy to address this as the bloom filter becomes saturated. To improve lookup performance, @ledjon-behluli implemented a blocked bloom filter[^3], which is used instead of a classic bloom filter.
[^1]: Efficient Computation of Frequent and Top-k Elements in Data Streams by Metwally, Agrawal, and Abbadi
[^2]: Finding top-k elements in data streams by Nuno Homem & Joao Paulo Carvalho
[^3]: Cache-, Hash- and Space-Efficient Bloom Filters by Felix Putze, Peter Sanders and Johannes Single
[^4]: The Power of Two Choices in Randomized Load Balancing by Michael David Mitzenmacher
Orleans v8.2.0 introduces a new API, RegisterGrainTimer
, for managing grain timers. For compatibility, the existing RegisterTimer
API is still available, but it is marked [Obsolete]
and developers should migrate to the new grain timer API, RegisterGrainTimer
.
Grain timers have been a common source of confusion for new and experienced developers because grain timer callbacks can execute concurrently with other grain calls, rather than being executed one-by-one like grain calls are. That is, timer callbacks are interleaving. With v8.2.0, this issue can be avoided by using the new RegisterGrainTimer
API. The new API has the following advantages:
Change(TimeSpan, TimeSpan)
method on the returned IGrainTimer
instance.Interleave
to true
on GrainTimerCreationOptions
.KeepAlive
to true
on GrainTimerCreationOptions
.CancellationToken
which is canceled when the timer is disposed or the grain starts to deactivate.Grain
) can register grain timers using the RegisterGrainTimer
extension method.The core API is as-follows:
public static IGrainTimer RegisterGrainTimer<TState>(this IGrainBase grain, Func<TState, CancellationToken, Task> callback, TState state, GrainTimerCreationOptions options);
There are various overloads for convenience:
public static IGrainTimer RegisterGrainTimer<TState>(this IGrainBase grain, Func<TState, CancellationToken, Task> callback, TState state, GrainTimerCreationOptions options);
public static IGrainTimer RegisterGrainTimer(this IGrainBase grain, Func<CancellationToken, Task> callback, GrainTimerCreationOptions options);
public static IGrainTimer RegisterGrainTimer(this IGrainBase grain, Func<Task> callback, GrainTimerCreationOptions options);
public static IGrainTimer RegisterGrainTimer<TState>(this IGrainBase grain, Func<TState, Task> callback, TState state, GrainTimerCreationOptions options);
public static IGrainTimer RegisterGrainTimer(this IGrainBase grain, Func<Task> callback, TimeSpan dueTime, TimeSpan period);
public static IGrainTimer RegisterGrainTimer(this IGrainBase grain, Func<CancellationToken, Task> callback, TimeSpan dueTime, TimeSpan period);
public static IGrainTimer RegisterGrainTimer<TState>(this IGrainBase grain, Func<TState, Task> callback, TState state, TimeSpan dueTime, TimeSpan period);
public static IGrainTimer RegisterGrainTimer<TState>(this IGrainBase grain, Func<TState, CancellationToken, Task> callback, TState state, TimeSpan dueTime, TimeSpan period);
The RegisterGrainTimer
API returns instances of IGrainTimer
instead of IDisposable
:
/// <summary>
/// Represents a timer belonging to a grain.
/// </summary>
public interface IGrainTimer : IDisposable
{
/// <summary>Changes the start time and the interval between method invocations for a timer, using <see cref="TimeSpan"/> values to measure time intervals.</summary>
/// <param name="dueTime">
/// A <see cref="TimeSpan"/> representing the amount of time to delay before invoking the callback method specified when the <see cref="IGrainTimer"/> was constructed.
/// Specify <see cref="Timeout.InfiniteTimeSpan"/> to prevent the timer from restarting.
/// Specify <see cref="TimeSpan.Zero"/> to restart the timer immediately.
/// </param>
/// <param name="period">
/// The time interval between invocations of the callback method specified when the timer was constructed.
/// Specify <see cref="Timeout.InfiniteTimeSpan"/> to disable periodic signaling.
/// </param>
/// <exception cref="ArgumentOutOfRangeException">The <paramref name="dueTime"/> or <paramref name="period"/> parameter, in milliseconds, is less than -1 or greater than 4294967294.</exception>
void Change(TimeSpan dueTime, TimeSpan period);
}
@n-sidorov implemented support for serializing messages using MessagePack.
To use MessagePack for message serialization, you will need to install Microsoft.Orleans.Serialization.MessagePack
by inserting the following into your project files:
<ItemGroup>
<PackageReference Include="Microsoft.Orleans.Serialization.MessagePack" Version="8.2.0" />
</ItemGroup>
Enable MessagePack serialization by calling ISerializerBuilder.AddMessagePackSerializer()
on your clients and silos:
builder.AddSerializer(serializer => serializer.AddMessagePackSerializer());
Upon doing so, Orleans will be able to serialize types with the [MessagePackObject]
attribute, for example:
[MessagePackObject]
public sealed record MyMessagePackClass
{
[Key(0)]
public int IntProperty { get; init; }
[Key(1)]
public string StringProperty { get; init; }
[Key(2)]
public MyMessagePackSubClass SubClass { get; init; }
}
@rkargMsft implemented support for using Cassandra as a backing store for clustering in https://github.com/dotnet/orleans/pull/8925.
To use Cassandra for clustering, you will need to install Microsoft.Orleans.Clustering.Cassandra
by inserting the following into your project files:
<ItemGroup>
<PackageReference Include="Microsoft.Orleans.Clustering.Cassandra" Version="8.2.0" />
</ItemGroup>
On your clients and silos, you can enable Cassandra clustering by calling:
builder.UseCassandraClustering(connectionString);
@JorgeCandeias implemented an ADO.NET streams provider in https://github.com/dotnet/orleans/pull/8974.
ADO.NET streaming is currently an alpha version. You can add it to your project files like so:
<ItemGroup>
<PackageReference Include="Microsoft.Orleans.Streaming.AdoNet" Version="8.2.0-alpha.1" />
</ItemGroup>
Configure ADO.NET streaming like so:
builder.AddAdoNetStreams("provider name", options =>
{
options.Invariant = "ADO.NET invariant name";
options.ConnectionString = "Connection string";
});
SafeTimer
usage, replace with PeriodicTimer
where possible by @ReubenBond in https://github.com/dotnet/orleans/pull/8953
Dictionary<K,V>
which add values in their constructor by @ReubenBond in https://github.com/dotnet/orleans/pull/8993
ConsistentRingProvider
& VirtualBucketsRingProvider
from ISiloStatusOracle
on shutdown by @ReubenBond in https://github.com/dotnet/orleans/pull/8997
Interlocked.Or
in SingleWaiterAutoResetEvent
by @ReubenBond in https://github.com/dotnet/orleans/pull/9003
List<T>
and HashSet<T>
by @ReubenBond in https://github.com/dotnet/orleans/pull/9005
PeriodicTimer
instead of GrainTimer
in LeaseBasedQueueBalancer
by @ReubenBond in https://github.com/dotnet/orleans/pull/9002
ActivationData
shutdown process by @ReubenBond in https://github.com/dotnet/orleans/pull/9018
StringData
in ATS provider by @ledjon-behluli in https://github.com/dotnet/orleans/pull/8965
MaxAvailableMemory
, add ActivationCount
factor by @ReubenBond in https://github.com/dotnet/orleans/pull/9028
PersistentStreamPullingAgent
by @ledjon-behluli in https://github.com/dotnet/orleans/pull/9035
MayInterleave
with StatelessWorker
grains by @ledjon-behluli in https://github.com/dotnet/orleans/pull/9050
RemoveStaleConditionalUpdates
by @zbarrier in https://github.com/dotnet/orleans/pull/8623
null
for no-op message observer to avoid interface call by @ReubenBond in https://github.com/dotnet/orleans/pull/9056
GetHashCode
implementations with HashCode.Combine
by @ReubenBond in https://github.com/dotnet/orleans/pull/9059
Full Changelog: https://github.com/dotnet/orleans/compare/v8.1.0...v8.2.0
Published by ReubenBond 5 months ago
SafeTimer
usage, replace with PeriodicTimer
where possible by @ReubenBond in https://github.com/dotnet/orleans/pull/8953
Dictionary<K,V>
which add values in their constructor by @ReubenBond in https://github.com/dotnet/orleans/pull/8993
ConsistentRingProvider
& VirtualBucketsRingProvider
from ISiloStatusOracle
on shutdown by @ReubenBond in https://github.com/dotnet/orleans/pull/8997
Interlocked.Or
in SingleWaiterAutoResetEvent
by @ReubenBond in https://github.com/dotnet/orleans/pull/9003
List<T>
and HashSet<T>
by @ReubenBond in https://github.com/dotnet/orleans/pull/9005
PeriodicTimer
instead of GrainTimer
in LeaseBasedQueueBalancer
by @ReubenBond in https://github.com/dotnet/orleans/pull/9002
ActivationData
shutdown process by @ReubenBond in https://github.com/dotnet/orleans/pull/9018
Full Changelog: https://github.com/dotnet/orleans/compare/v8.1.0...v8.2.0-preview1
Published by ReubenBond 5 months ago
Full Changelog: https://github.com/dotnet/orleans/compare/v3.7.1...v3.7.2
Published by ReubenBond 6 months ago
This release includes initial integration with .NET Aspire, allowing you to configure an Orleans cluster in your Aspire app host, specifying the resources the cluster uses. For example, you can specify that an Azure Table will be used for cluster membership, an Azure Redis resource will be used for the grain directory, and an Azure Blob Storage resource will be used to store grain state. The integration currently supports Redis and Azure Table & Blob storage resources. Support for other resources will be added later.
In the app host project, an Orleans cluster can be declared using the AddOrleans
method, and then configured with clustering, grain storage, grain directory, and other providers using methods on the returned builder:
var storage = builder.AddAzureStorage("storage");
var clusteringTable = storage.AddTables("clustering");
var defaultStorage = storage.AddBlobs("grainstate");
var cartStorage = builder.AddRedis("redis-cart");
var orleans = builder.AddOrleans("my-app")
.WithClustering(clusteringTable)
.WithGrainStorage("Default", grainStorage)
.WithGrainStorage("cart", cartStorage);
// Add a server project (also called "silo")
builder.AddProject<Projects.OrleansServer>("silo")
.WithReference(orleans);
// Add a project with a reference to the Orleans client
builder.AddProject<Projects.FrontEnd>("frontend")
.WithReference(orleans);
In the client and server projects, add Orleans to the host builder as usual.
// For an Orleans server:
builder.UseOrleans();
// Or, for an Orleans client:
builder.UseOrleansClient();
Orleans will read configuration created by your Aspire app host project and configure the providers specified therein. To allow Orleans to access the configured resources, add them as keyed services using the corresponding Aspire component:
builder.AddKeyedAzureTableService("clustering");
builder.AddKeyedAzureBlobService("grainstate");
builder.AddKeyedRedis("redis-cart");
Resource-optimized placement, enabled via the [ResourceOptimizedPlacement]
attribute on a grain class, balances grains across hosts based on available memory and CPU usage. For more details, see the PR: https://github.com/dotnet/orleans/pull/8815.
ResourceOptimizedPlacementOptions
to Orleans.Configuration
by @ledjon-behluli in https://github.com/dotnet/orleans/pull/8892
StatelessWorkerAttribute.MaxLocal
property is accounted for by @ReubenBond in https://github.com/dotnet/orleans/pull/8885
PooledBuffer
serialization by @ReubenBond in https://github.com/dotnet/orleans/pull/8852
RuntimeContext
to previous value after use by @ReubenBond in https://github.com/dotnet/orleans/pull/8864
LinearBackoffClientConnectionRetryFilter
in the default client services by @ledjon-behluli in https://github.com/dotnet/orleans/pull/8793
GenerateAliasAttribtuesAnalyzer
needs to account for file-scoped namespaces by @ledjon-behluli in https://github.com/dotnet/orleans/pull/8809
System.Data.SqlClient
by @ledjon-behluli in https://github.com/dotnet/orleans/pull/8821
OverloadDetector
to account for memory too by @ledjon-behluli in https://github.com/dotnet/orleans/pull/8820
RedisMembershipTable
by @ReubenBond in https://github.com/dotnet/orleans/pull/8848
Full Changelog: https://github.com/dotnet/orleans/compare/v8.0.0...v8.1.0
Published by ReubenBond 7 months ago
ResourceOptimizedPlacementOptions
to Orleans.Configuration
by @ledjon-behluli in https://github.com/dotnet/orleans/pull/8892
StatelessWorkerAttribute.MaxLocal
property is accounted for by @ReubenBond in https://github.com/dotnet/orleans/pull/8885
Full Changelog: https://github.com/dotnet/orleans/compare/v8.1.0-preview2...v8.1.0-preview3
Published by ReubenBond 7 months ago
Full Changelog: https://github.com/dotnet/orleans/compare/v7.2.5...v7.2.6
Published by ReubenBond 8 months ago
PooledBuffer
serialization by @ReubenBond in https://github.com/dotnet/orleans/pull/8852
RuntimeContext
to previous value after use by @ReubenBond in https://github.com/dotnet/orleans/pull/8864
Full Changelog: https://github.com/dotnet/orleans/compare/v8.1.0-preview1...v8.1.0-preview2
Published by ReubenBond 8 months ago
PooledBuffer
serialization & initialize ActivationMigrationManager on startup by @ReubenBond in https://github.com/dotnet/orleans/pull/8861
Full Changelog: https://github.com/dotnet/orleans/compare/v7.2.4...v7.2.5
Published by ReubenBond 8 months ago
This release includes initial integration with Aspire Preview 3 and later, allowing you to configure an Orleans cluster in your Aspire app host, specifying the resources the cluster uses. For example, you can specify that an Azure Table will be used for cluster membership, an Azure Redis resource will be used for the grain directory, and an Azure Blob Storage resource will be used to store grain state. The integration currently support Redis and Azure Table & Blob storage resources. Support for other resources will be added later.
In the app host project, an Orleans cluster can be declared using the AddOrleans
method, and then configured with clustering, grain storage, grain directory, and other providers using methods on the returned builder:
var storage = builder.AddAzureStorage("storage");
var clusteringTable = storage.AddTables("clustering");
var defaultStorage = storage.AddBlobs("grainstate");
var cartStorage = builder.AddRedis("redis-cart");
var orleans = builder.AddOrleans("my-app")
.WithClustering(clusteringTable)
.WithGrainStorage("Default", grainStorage)
.WithGrainStorage("cart", cartStorage);
// Add a server project (also called "silo")
builder.AddProject<Projects.OrleansServer>("silo")
.WithReference(orleans);
// Add a project with a reference to the Orleans client
builder.AddProject<Projects.FrontEnd>("frontend")
.WithReference(orleans);
In the client and server projects, add Orleans to the host builder as usual.
// For an Orleans server:
builder.UseOrleans();
// Or, for an Orleans client:
builder.UseOrleansClient();
Orleans will read configuration created by your Aspire app host project and configure the providers specified therein. To allow Orleans to access the configured resources, add them as keyed services using the corresponding Aspire component:
builder.AddKeyedAzureTableService("clustering");
builder.AddKeyedAzureBlobService("grainstate");
builder.AddKeyedRedis("redis-cart");
Resource-optimized placement, enabled via the [ResourceOptimizedPlacement]
attribute on a grain class, balances grains across hosts based on available memory and CPU usage. For more details, see the PR: https://github.com/dotnet/orleans/pull/8815.
LinearBackoffClientConnectionRetryFilter
in the default client services by @ledjon-behluli in https://github.com/dotnet/orleans/pull/8793
GenerateAliasAttribtuesAnalyzer
needs to account for file-scoped namespaces by @ledjon-behluli in https://github.com/dotnet/orleans/pull/8809
System.Data.SqlClient
by @ledjon-behluli in https://github.com/dotnet/orleans/pull/8821
OverloadDetector
to account for memory too by @ledjon-behluli in https://github.com/dotnet/orleans/pull/8820
RedisMembershipTable
by @ReubenBond in https://github.com/dotnet/orleans/pull/8848
Full Changelog: https://github.com/dotnet/orleans/compare/v8.0.0...v8.1.0-preview1
Published by ReubenBond 10 months ago
EndpointOptions
by @IEvangelist in https://github.com/dotnet/orleans/pull/8209
AddJsonSerializer
by @ReubenBond in https://github.com/dotnet/orleans/pull/8228
Collection<T>
serialization codec by @ReubenBond in https://github.com/dotnet/orleans/pull/8238
IGrainStorageSerializer
for memory grain storage by @shoneefd in https://github.com/dotnet/orleans/pull/8250
DeleteStateOnClear
for Redis grain storage. by @ReubenBond in https://github.com/dotnet/orleans/pull/8296
PooledArrayBufferWriter.AsMemory
by @ReubenBond in https://github.com/dotnet/orleans/pull/8300
IGrainFactory.GetGrain<T>
for unimplemented generic interfaces by @ReubenBond in https://github.com/dotnet/orleans/pull/8301
ActivationWorkingSet
by @ReubenBond in https://github.com/dotnet/orleans/pull/8321
null
in constructor by @bradygaster in https://github.com/dotnet/orleans/pull/8358
FormatterServices
to RuntimeHelpers
in preparation for .NET 8 by @ReubenBond in https://github.com/dotnet/orleans/pull/8362
DefaultOptionsFormatter
and DefaultOptionsFormatterResolver
by @ReubenBond in https://github.com/dotnet/orleans/pull/8384
DefaultStreamIdMapper
by @nichvolodov in https://github.com/dotnet/orleans/pull/8378
IAsyncEnumerable<T>
support for grain calls by @ReubenBond in https://github.com/dotnet/orleans/pull/8416
PooledArrayBufferWriter
more versatile, rename by @ReubenBond in https://github.com/dotnet/orleans/pull/8453
void
methods: VoidRequest
implies OneWay
by @ReubenBond in https://github.com/dotnet/orleans/pull/8468
HostApplicationBuilder
extensions by @IEvangelist in https://github.com/dotnet/orleans/pull/8466
UsingDirective
insertion in [NonSerialized]
codefix by @ReubenBond in https://github.com/dotnet/orleans/pull/8557
readonly
where applicable by @ReubenBond in https://github.com/dotnet/orleans/pull/8587
required
members by @ReubenBond in https://github.com/dotnet/orleans/pull/8595
[RegexImplicitChannelSubscription(...)]
and [RegexImplicitStreamSubscription(...)]
by @ReubenBond in https://github.com/dotnet/orleans/pull/8597
ImplicitStreamSubscriptionAttribute.StreamIdMapper
to be initialized by subclasses by @ReubenBond in https://github.com/dotnet/orleans/pull/8592
ClusterMembershipOptions.NumVotesForDeathDeclaration
is not greater than NumProbedSilos
on startup by @ReubenBond in https://github.com/dotnet/orleans/pull/8679
CollectionAgeLimitAttribute
by @ReubenBond in https://github.com/dotnet/orleans/pull/8681
Service
comment by @qin-guan in https://github.com/dotnet/orleans/pull/8745
CompoundTypeAliasTree
with isolated base interface(s) by @ledjon-behluli in https://github.com/dotnet/orleans/pull/8788
Full Changelog: https://github.com/dotnet/orleans/compare/v7.0.0...v8.0.0
Published by ReubenBond 10 months ago
CompoundTypeAliasTree
with isolated base interface(s) by @ledjon-behluli in https://github.com/dotnet/orleans/pull/8788
Full Changelog: https://github.com/dotnet/orleans/compare/v8.0.0-rc1...v8.0.0-rc2
Published by ReubenBond 11 months ago
EndpointOptions
by @IEvangelist in https://github.com/dotnet/orleans/pull/8209
AddJsonSerializer
by @ReubenBond in https://github.com/dotnet/orleans/pull/8228
Collection<T>
serialization codec by @ReubenBond in https://github.com/dotnet/orleans/pull/8238
IGrainStorageSerializer
for memory grain storage by @shoneefd in https://github.com/dotnet/orleans/pull/8250
DeleteStateOnClear
for Redis grain storage. by @ReubenBond in https://github.com/dotnet/orleans/pull/8296
PooledArrayBufferWriter.AsMemory
by @ReubenBond in https://github.com/dotnet/orleans/pull/8300
IGrainFactory.GetGrain<T>
for unimplemented generic interfaces by @ReubenBond in https://github.com/dotnet/orleans/pull/8301
ActivationWorkingSet
by @ReubenBond in https://github.com/dotnet/orleans/pull/8321
null
in constructor by @bradygaster in https://github.com/dotnet/orleans/pull/8358
FormatterServices
to RuntimeHelpers
in preparation for .NET 8 by @ReubenBond in https://github.com/dotnet/orleans/pull/8362
DefaultOptionsFormatter
and DefaultOptionsFormatterResolver
by @ReubenBond in https://github.com/dotnet/orleans/pull/8384
DefaultStreamIdMapper
by @nichvolodov in https://github.com/dotnet/orleans/pull/8378
IAsyncEnumerable<T>
support for grain calls by @ReubenBond in https://github.com/dotnet/orleans/pull/8416
PooledArrayBufferWriter
more versatile, rename by @ReubenBond in https://github.com/dotnet/orleans/pull/8453
void
methods: VoidRequest
implies OneWay
by @ReubenBond in https://github.com/dotnet/orleans/pull/8468
HostApplicationBuilder
extensions by @IEvangelist in https://github.com/dotnet/orleans/pull/8466
UsingDirective
insertion in [NonSerialized]
codefix by @ReubenBond in https://github.com/dotnet/orleans/pull/8557
readonly
where applicable by @ReubenBond in https://github.com/dotnet/orleans/pull/8587
required
members by @ReubenBond in https://github.com/dotnet/orleans/pull/8595
[RegexImplicitChannelSubscription(...)]
and [RegexImplicitStreamSubscription(...)]
by @ReubenBond in https://github.com/dotnet/orleans/pull/8597
ImplicitStreamSubscriptionAttribute.StreamIdMapper
to be initialized by subclasses by @ReubenBond in https://github.com/dotnet/orleans/pull/8592
ClusterMembershipOptions.NumVotesForDeathDeclaration
is not greater than NumProbedSilos
on startup by @ReubenBond in https://github.com/dotnet/orleans/pull/8679
CollectionAgeLimitAttribute
by @ReubenBond in https://github.com/dotnet/orleans/pull/8681
Service
comment by @qin-guan in https://github.com/dotnet/orleans/pull/8745
Other changes have been backported to 7.x
Service
comment by @qin-guan in https://github.com/dotnet/orleans/pull/8745
Full Changelog: https://github.com/dotnet/orleans/compare/v7.0.0...v8.0.0-rc1
Published by ReubenBond 11 months ago
Full Changelog: https://github.com/dotnet/orleans/compare/v7.2.3...v7.2.4
Published by ReubenBond 12 months ago
ClusterMembershipOptions.NumVotesForDeathDeclaration
is not greater than NumProbedSilos
on startup by @ReubenBond in https://github.com/dotnet/orleans/pull/8679
CollectionAgeLimitAttribute
by @ReubenBond in https://github.com/dotnet/orleans/pull/8681
Full Changelog: https://github.com/dotnet/orleans/compare/v7.2.2...v7.2.3
Published by ReubenBond about 1 year ago
MayInterleave
predicates by @blazknuplez in https://github.com/dotnet/orleans/pull/8548
Dictionary<K,V>
by @ReubenBond in https://github.com/dotnet/orleans/pull/8552
DefaultGrainActivator
and GrainConstructorArgumentFactory
for customization by @ReubenBond in https://github.com/dotnet/orleans/pull/8550
ValueTuple
tests by @Romanx in https://github.com/dotnet/orleans/pull/8566
ISpanParsable
on to GrainId
by @Romanx in https://github.com/dotnet/orleans/pull/8565
UsingDirective
insertion in [NonSerialized]
codefix by @ReubenBond in https://github.com/dotnet/orleans/pull/8557
IGrainDirectory
and implementers. by @Romanx in https://github.com/dotnet/orleans/pull/8570
IGrainReminder
in GrainReminderExtensions
by @JRWinter1 in https://github.com/dotnet/orleans/pull/8544
CachedGrainLocator
Unregister Ordering by @JohnMorman in https://github.com/dotnet/orleans/pull/8547
StreamId
keys by @AdrianoAE in https://github.com/dotnet/orleans/pull/8578
readonly
where applicable by @ReubenBond in https://github.com/dotnet/orleans/pull/8587
IRemoteGrainDirectory
API by @ReubenBond in https://github.com/dotnet/orleans/pull/8593
required
members by @ReubenBond in https://github.com/dotnet/orleans/pull/8595
PubSubPublisherState
by @ReubenBond in https://github.com/dotnet/orleans/pull/8594
TimeSpan
string syntax by @ReubenBond in https://github.com/dotnet/orleans/pull/8596
[RegexImplicitChannelSubscription(...)]
and [RegexImplicitStreamSubscription(...)]
by @ReubenBond in https://github.com/dotnet/orleans/pull/8597
ImplicitStreamSubscriptionAttribute.StreamIdMapper
to be initialized by subclasses by @ReubenBond in https://github.com/dotnet/orleans/pull/8592
IActivator<T>
instead of Activator.CreateInstance
to handle unserializable types by @AdrianoAE in https://github.com/dotnet/orleans/pull/8626
GrainDirectoryResolver
, replace HasNonDefaultDirectory
with IsUsingDhtDirectory
by @benjaminpetit in https://github.com/dotnet/orleans/pull/8660
Full Changelog: https://github.com/dotnet/orleans/compare/v7.2.1...v7.2.2
Published by ReubenBond over 1 year ago
Full Changelog: https://github.com/dotnet/orleans/compare/v7.2.0...v7.2.1
Published by ReubenBond over 1 year ago
IAsyncEnumerable<T>
(PR: https://github.com/dotnet/orleans/pull/8416)IAsyncEnumerable<T>
support for grain calls by @ReubenBond in https://github.com/dotnet/orleans/pull/8416
PooledArrayBufferWriter
more versatile, rename by @ReubenBond in https://github.com/dotnet/orleans/pull/8453
void
methods: VoidRequest
implies OneWay
by @ReubenBond in https://github.com/dotnet/orleans/pull/8468
HostApplicationBuilder
extensions by @IEvangelist in https://github.com/dotnet/orleans/pull/8466
Full Changelog: https://github.com/dotnet/orleans/compare/v7.1.2...v7.2.0
Published by ReubenBond over 1 year ago
This release fixes a reliability bug in Orleans.Transactions
readyTask
failures are recovered from by @ReubenBond in https://github.com/dotnet/orleans/pull/8443
Full Changelog: https://github.com/dotnet/orleans/compare/v3.7.0...v3.7.1
Published by ReubenBond over 1 year ago
null
in constructor by @bradygaster in https://github.com/dotnet/orleans/pull/8358
FormatterServices
to RuntimeHelpers
in preparation for .NET 8 by @ReubenBond in https://github.com/dotnet/orleans/pull/8362
DefaultOptionsFormatter
and DefaultOptionsFormatterResolver
by @ReubenBond in https://github.com/dotnet/orleans/pull/8384
DefaultStreamIdMapper
by @nichvolodov in https://github.com/dotnet/orleans/pull/8378
Full Changelog: https://github.com/dotnet/orleans/compare/v7.1.1...v7.1.2
Published by ReubenBond over 1 year ago
ITypeFilter
and ITypeNameFilter
by @ReubenBond in https://github.com/dotnet/orleans/pull/8328
ActivationWorkingSet
by @ReubenBond in https://github.com/dotnet/orleans/pull/8321
Full Changelog: https://github.com/dotnet/orleans/compare/v7.1.0...v7.1.1