Skip to content

Convert some uses of passive voice to active voice in Orleans docs #45474

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Mar 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/orleans/grains/grain-identity.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The following sections discuss grain type names and grain keys in more detail.

Orleans creates a grain type name for you based on your grain implementation class by removing the suffix "Grain" from the class name, if it's present, and converting the resulting string into its lower-case representation. For example, a class named `ShoppingCartGrain` will be given the grain type name `shoppingcart`. It's recommended that grain type names and keys consist only of printable characters such as alpha-numeric (`a`-`z`, `A`-`Z`, and `0`-`9`) characters and symbols such as `-`, `_`, `@`, `=`. Other characters may or may not be supported and will often need special treatment when printed in logs or appearing as identifiers in other systems such as databases.

Alternatively, the <xref:Orleans.GrainTypeAttribute?displayProperty=nameWithType> attribute can be used to customize the grain type name for the grain class which it is attached to, as in the following example:
Alternatively, you can use the <xref:Orleans.GrainTypeAttribute?displayProperty=nameWithType> attribute to customize the grain type name for the grain class to which it is attached, as in the following example:

```csharp
[GrainType("cart")]
Expand Down
4 changes: 2 additions & 2 deletions docs/orleans/grains/grain-placement.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ Orleans ensures that when a grain call is made there is an instance of that grai

The placement process in Orleans is fully configurable: developers can choose from a set of out-of-the-box placement policies such as random, prefer-local, and load-based, or custom logic can be configured. This allows for full flexibility in deciding where grains are created. For example, grains can be placed on a server close to resources which they need to operate on or close to other grains with which they communicate. By default, Orleans will pick a random compatible server.

The placement strategy which Orleans uses can be configured globally or per-grain-class.
The placement strategy that Orleans uses can be configured globally or per grain class.

## Random placement

A server is randomly selected from the compatible servers in the cluster. This placement strategy is configured by adding the <xref:Orleans.Placement.RandomPlacementAttribute> to a grain.
A server is randomly selected from the compatible servers in the cluster. To configure this placement strategy, add the <xref:Orleans.Placement.RandomPlacementAttribute> to a grain.

## Local placement

Expand Down
2 changes: 1 addition & 1 deletion docs/orleans/grains/request-scheduling.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ In this example, grains *A* and *B* can call each other simultaneously without a

The <xref:Orleans.Grain> implementation classes may be marked with the <xref:Orleans.Concurrency.ReentrantAttribute> to indicate that different requests may be freely interleaved.

In other words, a re-entrant activation may start executing another request while a previous request hasn't finished processing. Execution is still limited to a single thread, so the activation is still executing one turn at a time, and each turn is executing on behalf of only one of the activation's requests.
In other words, a re-entrant activation might start another request while a previous request hasn't finished processing. Execution is still limited to a single thread, so the activation is still executing one turn at a time, and each turn is executing on behalf of only one of the activation's requests.

Re-entrant grain code never runs multiple pieces of grain code in parallel (execution of grain code is always single-threaded), but re-entrant grains **may** see the execution of code for different requests interleaving. That is, the continuation turns from different requests may interleave.

Expand Down
2 changes: 1 addition & 1 deletion docs/orleans/grains/stateless-worker-grains.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ By default, the Orleans runtime creates no more than one activation of a grain w
When the <xref:Orleans.Concurrency.StatelessWorkerAttribute> is applied to a grain class, it indicates to the Orleans runtime that grains of that class should be treated as stateless worker grains. Stateless worker grains have the following properties that make their execution very different from that of normal grain classes.

1. The Orleans runtime can and will create multiple activations of a stateless worker grain on different silos of the cluster.
1. Requests made to stateless worker grains are executed locally as long as the silo is compatible, and therefore they will not incur networking or serialization costs. If the local silo is not compatible, requests are forwarded to a compatible silo.
1. Stateless worker grains execute requests locally as long as the silo is compatible, and therefore don't incur networking or serialization costs. If the local silo is not compatible, requests are forwarded to a compatible silo.
1. The Orleans Runtime automatically creates additional activations of a stateless worker grain if the already existing ones are busy.
The maximum number of activations of a stateless worker grain the runtime creates per silo is limited by default by the number of CPU cores on the machine, unless specified explicitly by the optional `maxLocalWorkers` argument.
1. Because of 2 and 3, stateless worker grain activations are not individually addressable. Two subsequent requests to a stateless worker grain may be processed by different activations of it.
Expand Down
2 changes: 1 addition & 1 deletion docs/orleans/grains/timers-and-reminders.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Reminders are similar to timers, with a few important differences:

## Configuration

Reminders, being persistent, rely upon storage to function. You must specify which storage backing to use before the reminder subsystem functions. This is done by configuring one of the reminder providers via `Use{X}ReminderService` extension methods, where `X` is the name of the provider, for example, <xref:Orleans.Hosting.SiloHostBuilderReminderExtensions.UseAzureTableReminderService%2A>.
Since reminders are persistent, they rely upon storage to function. You must specify which storage backing to use before the reminder subsystem functions. You do this by configuring one of the reminder providers via `Use{X}ReminderService` extension methods, where `X` is the name of the provider, for example, <xref:Orleans.Hosting.SiloHostBuilderReminderExtensions.UseAzureTableReminderService%2A>.

Azure Table configuration:

Expand Down
4 changes: 2 additions & 2 deletions docs/orleans/host/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ zone_pivot_groups: orleans-version

# Orleans clients

A client allows non-grain code to interact with an Orleans cluster. Clients allow application code to communicate with grains and streams hosted in a cluster. There are two ways to obtain a client, depending on where the client code is hosted: in the same process as a silo, or in a separate process. This article will discuss both options, starting with the recommended option: co-hosting the client code in the same process as the grain code.
A client allows non-grain code to interact with an Orleans cluster. Clients allow application code to communicate with grains and streams hosted in a cluster. There are two ways to obtain a client, depending on where you host the client code: in the same process as a silo, or in a separate process. This article discusses both options, starting with the recommended option: co-hosting the client code in the same process as the grain code.

## Co-hosted clients

If the client code is hosted in the same process as the grain code, then the client can be directly obtained from the hosting application's dependency injection container. In this case, the client communicates directly with the silo it is attached to and can take advantage of the extra knowledge that the silo has about the cluster.
If you host the client code in the same process as the grain code, then you can directly obtain the client from the hosting application's dependency injection container. In this case, the client communicates directly with the silo it is attached to and can take advantage of the extra knowledge that the silo has about the cluster.

This provides several benefits, including reducing network and CPU overhead as well as decreasing latency and increasing throughput and reliability. The client utilizes the silo's knowledge of the cluster topology and state and does not need to use a separate gateway. This avoids a network hop and serialization/deserialization round trip. This therefore also increases reliability, since the number of required nodes in between the client and the grain is minimized. If the grain is a [stateless worker grain](../grains/stateless-worker-grains.md) or otherwise happens to be activated on the silo where the client is hosted, then no serialization or network communication needs to be performed at all and the client can reap the additional performance and reliability gains. Co-hosting client and grain code also simplifies deployment and application topology by eliminating the need for two distinct application binaries to be deployed and monitored.

Expand Down
2 changes: 1 addition & 1 deletion docs/orleans/host/grain-directory.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ms.date: 07/03/2024

# Orleans grain directory

Grains have stable logical identities and may get activated (instantiated) and deactivated many times over the life of the application, but at most one activation of grain exist at any point in time. Each time a grain gets activated, it may be placed on a different silo in the cluster. When a grain gets activated in the cluster, it gets registered in the global registry, _grain directory_. This ensures that subsequent invocations of that grain will be delivered to that activation of the grain and that no other activations (instances) of that grain will be created. The grain directory is responsible for keeping a mapping between a grain identity and where (which silo) its current activation is at.
Grains have stable logical identities and may get activated (instantiated) and deactivated many times over the life of the application, but at most one activation of grain exist at any point in time. Each time a grain gets activated, it may be placed on a different silo in the cluster. When a grain gets activated in the cluster, it registers itself in the _grain directory_. This ensures that subsequent invocations of that grain will be delivered to that activation of the grain and that no other activations (instances) of that grain will be created. The grain directory is responsible for keeping a mapping between a grain identity and where (which silo) its current activation is at.

By default, Orleans uses a built-in distributed in-memory directory. This directory is eventually consistent and partitioned across all silos in the cluster in a form of a distributed hash table.

Expand Down
2 changes: 1 addition & 1 deletion docs/orleans/implementation/cluster-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ In addition to the <xref:Orleans.IMembershipTable> each silo participates in a f

### The membership protocol

1. Upon startup every silo adds an entry for itself into a well-known, shared table, using an implementation of <xref:Orleans.IMembershipTable>. A combination of silo identity (`ip:port:epoch`) and service deployment id (cluster id) is used as unique keys in the table. Epoch is just time in ticks when this silo started, and as such `ip:port:epoch` is guaranteed to be unique in a given Orleans deployment.
1. Upon startup every silo adds an entry for itself into a well-known, shared table, using an implementation of <xref:Orleans.IMembershipTable>. Orleans uses a combination of silo identity (`ip:port:epoch`) and service deployment ID (cluster ID) as unique keys in the table. Epoch is just time in ticks when this silo started, and as such `ip:port:epoch` is guaranteed to be unique in a given Orleans deployment.

1. Silos monitor each other directly, via application probes ("are you alive" `heartbeats`). probes are sent as direct messages from silo to silo, over the same TCP sockets that silos communicate. That way, probes fully correlate with actual networking problems and server health. Every silo probes a configurable set of other silos. A silo picks whom to probe by calculating consistent hashes on other silos' identity, forming a virtual ring of all identities, and picking X successor silos on the ring (this is a well-known distributed technique called [consistent hashing](https://en.wikipedia.org/wiki/Consistent_hashing) and is widely used in many distributed hash tables, like [Chord DHT](https://en.wikipedia.org/wiki/Chord_(peer-to-peer))).

Expand Down
2 changes: 1 addition & 1 deletion docs/orleans/implementation/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ ms.date: 07/03/2024
## [Orleans Lifecycle](orleans-lifecycle.md)

Some Orleans behaviors are sufficiently complex that they need ordered startup and shutdown.
To address this, a general component lifecycle pattern has been introduced.
To address this, Orleans introduced a general component lifecycle pattern.

## [Messaging delivery guarantees](messaging-delivery-guarantees.md)

Expand Down
2 changes: 1 addition & 1 deletion docs/orleans/implementation/orleans-lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ms.date: 07/03/2024

# Orleans lifecycle overview

Some Orleans behaviors are sufficiently complex that they need ordered startup and shutdown. Some components with such behaviors include grains, silos, and clients. To address this, a general component lifecycle pattern has been introduced. This pattern consists of an observable lifecycle, which is responsible for signaling on stages of a component's startup and shutdown, and lifecycle observers which are responsible for performing startup or shutdown operations at specific stages.
Some Orleans behaviors are sufficiently complex that they need ordered startup and shutdown. Some components with such behaviors include grains, silos, and clients. To address this, Orleans introduced a general component lifecycle pattern. This pattern consists of an observable lifecycle, which is responsible for signaling on stages of a component's startup and shutdown, and lifecycle observers, which are responsible for performing startup or shutdown operations at specific stages.

For more information, see [Grain lifecycle](../grains/grain-lifecycle.md) and [Silo lifecycle](../host/silo-lifecycle.md).

Expand Down
2 changes: 1 addition & 1 deletion docs/orleans/implementation/scheduler.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Here is a graphical representation of how a request is scheduled and executed as

:::image type="content" source="media/scheduler/scheduling-1.png" alt-text="Two-Task-based request execution example.":::

The above description is not specific to Orleans and is how task scheduling in .NET works: asynchronous methods in C# are converted into an asynchronous state machine by the compiler and execution progresses through the asynchronous state machine in discrete steps. Each step is scheduled on the current <xref:System.Threading.Tasks.TaskScheduler> (accessed via <xref:System.Threading.Tasks.TaskScheduler.Current?displayProperty=nameWithType>, defaulting to <xref:System.Threading.Tasks.TaskScheduler.Default?displayProperty=nameWithType>) or the current <xref:System.Threading.SynchronizationContext>. If a `TaskScheduler` is being used, each step in the method is represented by a `Task` instance which is passed to that `TaskScheduler`. Therefore, a `Task` in .NET can represent two conceptual things:
The above description is not specific to Orleans; it describes how task scheduling in .NET works: the compiler converts asynchronous methods in C# into an asynchronous state machine, and execution progresses through the asynchronous state machine in discrete steps. Each step is scheduled on the current <xref:System.Threading.Tasks.TaskScheduler> (accessed via <xref:System.Threading.Tasks.TaskScheduler.Current?displayProperty=nameWithType>, defaulting to <xref:System.Threading.Tasks.TaskScheduler.Default?displayProperty=nameWithType>) or the current <xref:System.Threading.SynchronizationContext>. If a `TaskScheduler` is being used, each step in the method represents a `Task` instance, which is passed to that `TaskScheduler`. Therefore, a `Task` in .NET can represent two conceptual things:

1. An asynchronous operation that can be waited on. The execution of the `DelayExecution()` method above is represented by a `Task` which can be awaited.
1. In a synchronous block of work, each stage within the `DelayExecution()` method above is represented by a `Task`.
Expand Down
2 changes: 1 addition & 1 deletion docs/orleans/implementation/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ You can now reuse a `TestCluster` in your test cases:

:::code source="snippets/testing/Orleans-testing/Sample.OrleansTesting/HelloGrainTestsWithFixture.cs":::

xUnit calls the <xref:System.IDisposable.Dispose> method of the `ClusterFixture` type when all tests have been completed and the in-memory cluster silos are stopped. `TestCluster` also has a constructor that accepts <xref:Orleans.TestingHost.TestClusterOptions> that can be used to configure the silos in the cluster.
When all tests have been completed and the in-memory cluster silos are stopped, xUnit calls the <xref:System.IDisposable.Dispose> method of the `ClusterFixture` type. `TestCluster` also has a constructor that accepts <xref:Orleans.TestingHost.TestClusterOptions> that you can use to configure the silos in the cluster.

If you're using Dependency Injection in your Silo to make services available to Grains, you can use this pattern as well:

Expand Down
2 changes: 1 addition & 1 deletion docs/orleans/migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Orleans 7.0 introduces several beneficial changes, including improvements to hos

## Migration

Existing applications using reminders, streams, or grain persistence cannot be easily migrated to Orleans 7.0 due to changes in how Orleans identifies grains and streams. We plan to incrementally offer a migration path for these applications.
Due to changes in how Orleans identifies grains and streams, you cannot (currently) easily migrate existing applications using reminders, streams, or grain persistence to Orleans 7.0.

Applications running previous versions of Orleans cannot be smoothly upgraded via a rolling upgrade to Orleans 7.0. Therefore, a different upgrade strategy must be used, such as deploying a new cluster and decommissioning the previous cluster. Orleans 7.0 changes the wire protocol in an incompatible fashion, meaning that clusters cannot contain a mix of Orleans 7.0 hosts and hosts running previous versions of Orleans.

Expand Down
2 changes: 1 addition & 1 deletion docs/orleans/resources/best-practices.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Grains (virtual actors) are the base building blocks of an Orleans-based applica

## Suitable apps

Orleans should be considered when:
Consider Orleans when:

- Significant number (hundreds, millions, billions, and even trillions) of loosely coupled entities. To put the number in perspective, Orleans can easily create a grain for every person on Earth in a small cluster, so long as a subset of that total number is active at any point in time.
- Examples: user profiles, purchase orders, application/game sessions, stocks.
Expand Down
6 changes: 3 additions & 3 deletions docs/orleans/resources/frequently-asked-questions.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ In this article, you will find answers to the most common questions about .NET O

### Can I freely use Orleans in my project?

Absolutely. The source code has been released under the [MIT license](https://github.com/dotnet/orleans/blob/main/LICENSE). NuGet packages are published on [nuget.org](https://www.nuget.org/profiles/Orleans).
Absolutely. The source code is licensed under the [MIT license](https://github.com/dotnet/orleans/blob/main/LICENSE). NuGet packages are published on [nuget.org](https://www.nuget.org/profiles/Orleans).

### Is Orleans production ready? I heard it's a research project.

Orleans, indeed, initially started as a research project within Microsoft Research. It later grew into a product and has been used in production within Microsoft since 2011, and by other companies, after it was publicly released in 2015. Orleans is production-ready and powers many highly available systems and cloud services.
Orleans started as a research project within Microsoft Research. It later grew into a production-ready product and has been used in production within Microsoft (since 2011) and by other companies (since it was publicly released in 2015). Orleans powers many highly available systems and cloud services.

### Does Microsoft support Orleans?

Source code of Orleans has been released under an MIT license on [GitHub](https://github.com/dotnet/orleans). Microsoft continues to invest in Orleans and accepts community contributions to the codebase.
Microsoft released the source code of Orleans under an MIT license on [GitHub](https://github.com/dotnet/orleans). Microsoft continues to invest in Orleans and accepts community contributions to the codebase.

## Positioning

Expand Down
Loading