<commit_before># Jasper as Command Bus

::: tip
The in memory queueing feature is automatically enabled for all Jasper applications, and any possible message can
be enqueued locally.
:::

Jasper can be used as an in-memory, command bus where messages can be processed either immediately or through
in memory queues within your application. The queueing is all based around the [TPL Dataflow library](https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-perform-action-when-a-dataflow-block-receives-data) objects from the [TPL Dataflow](https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/dataflow-task-parallel-library) library.
As such, you have a fair amount of control over parallelization and even some back pressure. These local queues can be used directly, or as a transport to accept messages sent through
`IMessagePublisher.SendAsync()` or `IMessagePublisher.PublishAsync()`. using the application's [message routing rules](/guide/messaging/#routing-rules).

## Enqueueing Messages Locally

::: tip warning
The `IMessagePublisher` and `IExecutionContext` interfaces both implement the `ICommandBus` interface, and truth be told,
it's just one underlying concrete class and the interfaces just expose narrower or broader options.
:::

You can queue up messages to be executed asynchronously:

<!-- snippet: sample_enqueue_locally -->
<a id='snippet-sample_enqueue_locally'></a>
```cs
public static async Task enqueue_locally(ICommandBus bus)
{
    // Enqueue a message to the local worker queues
    await bus.EnqueueAsync(new Message1());

}
```
<sup><a href='https://github.com/JasperFx/alba/blob/master/src/Samples/DocumentationSamples/EnqueueSamples.cs#L8-L16' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_enqueue_locally' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

This feature is useful for asynchronous processing in web applications or really any kind of application where you need some parallelization or concurrency.

Some things to know about the local queues:

* Local worker queues can be durable, meaning that the enqueued messages are persisted first so that they aren't lost if the application is shut down before they're processed. More on that below.
* You can use any number of named local queues, and they don't even have to be declared upfront (might want to be careful with that though)
* Local worker queues utilize Jasper's [error handling](/guide/messages/error-handling) policies to selectively handle any detected exceptions from the [message handlers](http://localhost:5050/guide/messages/handlers).
* You can control the priority and parallelization of each individual local queue
* Message types can be routed to particular queues
* [Cascading messages](/guide/messages/handlers.html#cascading-messages-from-actions) can be used with the local queues
* The local queues can be used like any other message transport and be the target of routing rules




## The Default Queue

Out of the box, each Jasper application has a default queue named "default". In the absence of any
other routing rules, all messages enqueued to `ICommandBus` will be published to this queue. The default in memory
queue can be configured like this:

<!-- snippet: sample_ConfigureDefaultQueue -->
<a id='snippet-sample_configuredefaultqueue'></a>
```cs
using var host = await Host.CreateDefaultBuilder()
    .UseJasper(opts =>
    {
        opts.DefaultLocalQueue.MaximumParallelMessages(3);
    }).StartAsync();
```
<sup><a href='https://github.com/JasperFx/alba/blob/master/src/Samples/DocumentationSamples/ConfigureDurableLocalQueueApp.cs#L28-L36' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_configuredefaultqueue' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

## Local Message Routing

In the absence of any kind of routing rules, any message enqueued with `ICommandBus.Enqueue()` will just be handled by the
*default* local queue. To override that choice on a message type by message type basis, you can use the `[LocalQueue]` attribute
on a message type:

<!-- snippet: sample_local_queue_routed_message -->
<a id='snippet-sample_local_queue_routed_message'></a>
```cs
[LocalQueue("important")]
public class ImportanceMessage
{

}
```
<sup><a href='https://github.com/JasperFx/alba/blob/master/src/Samples/DocumentationSamples/LocalQueueMessage.cs#L5-L12' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_local_queue_routed_message' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

Otherwise, you can take advantage of Jasper's message routing rules like this:

<!-- snippet: sample_LocalTransportApp -->
<a id='snippet-sample_localtransportapp'></a>
```cs
using var host = await Host.CreateDefaultBuilder()
    .UseJasper(opts =>
    {
        // Publish Message2 messages to the "important"
        // local queue
        opts.PublishMessage<Message2>()
            .ToLocalQueue("important");
    }).StartAsync();
```
<sup><a href='https://github.com/JasperFx/alba/blob/master/src/Samples/DocumentationSamples/MessagingConfigurationExamples.cs#L104-L115' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_localtransportapp' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

The routing rules and/or `[LocalQueue]` routing is also honored for cascading messages, meaning that any message that is handled inside a Jasper system could publish cascading messages to the local worker queues.

See [message routing rules](/guide/messaging/#routing-rules) for more information.

## Durable Local Messages

The local worker queues can optionally be designated as "durable," meaning that local messages would be persisted until they can be successfully processed to provide a guarantee that the message will be successfully processed in the case of the running application faulting or having been shut down prematurely (assuming that other nodes are running or it's restarted later of course).

Here is an example of configuring a local queue to be durable:

<!-- snippet: sample_LocalDurableTransportApp -->
<a id='snippet-sample_localdurabletransportapp'></a>
```cs
using var host = await Host.CreateDefaultBuilder()
    .UseJasper(opts =>
    {
        // Make the default local queue durable
        opts.DefaultLocalQueue.DurablyPersistedLocally();

        // Or do just this by name
        opts.LocalQueue("important")
            .DurablyPersistedLocally();
    }).StartAsync();
```
<sup><a href='https://github.com/JasperFx/alba/blob/master/src/Samples/DocumentationSamples/MessagingConfigurationExamples.cs#L124-L137' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_localdurabletransportapp' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->


See [Persistent Messaging](http://localhost:5050/guide/persistence/) for more information.


## Scheduling Local Execution

The "scheduled execution" feature can be used with local execution within the same application. See [Scheduled Messages](/guide/scheduled) for more information. Use the `ICommandBus.ScheduleAsync()` methods like this:<commit_msg>Little clean up on command bus docs<commit_after># Jasper as Command Bus

::: tip
The in memory queueing feature is automatically enabled for all known message types within all Jasper applications.
:::

Jasper can be used as an in-memory, command bus where messages can be processed either immediately or through
in memory queues within your application. The queueing is all based around the [TPL Dataflow library](https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-perform-action-when-a-dataflow-block-receives-data) objects from the [TPL Dataflow](https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/dataflow-task-parallel-library) library.
As such, you have a fair amount of control over parallelization and even some back pressure. These local queues can be used directly, or as a transport to accept messages sent through
`IMessagePublisher.SendAsync()` or `IMessagePublisher.PublishAsync()`. using the application's [message routing rules](/guide/messaging/#routing-rules).

## Enqueueing Messages Locally

::: tip warning
The `IMessagePublisher` and `IExecutionContext` interfaces both implement the `ICommandBus` interface as well.
:::

You can queue up messages to be executed locally and asynchronously in a background thread:

<!-- snippet: sample_enqueue_locally -->
<a id='snippet-sample_enqueue_locally'></a>
```cs
public static async Task enqueue_locally(ICommandBus bus)
{
    // Enqueue a message to the local worker queues
    await bus.EnqueueAsync(new Message1());

}
```
<sup><a href='https://github.com/JasperFx/alba/blob/master/src/Samples/DocumentationSamples/EnqueueSamples.cs#L8-L16' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_enqueue_locally' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

This feature is useful for asynchronous processing in web applications or really any kind of application where you need some parallelization or concurrency.

Some things to know about the local queues:

* Local worker queues can be durable, meaning that the enqueued messages are persisted first so that they aren't lost if the application is shut down before they're processed. More on that below.
* You can use any number of named local queues, and they don't even have to be declared upfront (might want to be careful with that though)
* Local worker queues utilize Jasper's [error handling](/guide/messages/error-handling) policies to selectively handle any detected exceptions from the [message handlers](/guide/messages/handlers).
* You can control the priority and parallelization of each individual local queue
* Message types can be routed to particular queues
* [Cascading messages](/guide/messages/handlers.html#cascading-messages-from-actions) can be used with the local queues
* The local queues can be used like any other message transport and be the target of routing rules




## The Default Queue

Out of the box, each Jasper application has a default queue named "default". In the absence of any
other routing rules, all messages enqueued to `ICommandBus` will be published to this queue. The default in memory
queue can be configured like this:

<!-- snippet: sample_ConfigureDefaultQueue -->
<a id='snippet-sample_configuredefaultqueue'></a>
```cs
using var host = await Host.CreateDefaultBuilder()
    .UseJasper(opts =>
    {
        opts.DefaultLocalQueue.MaximumParallelMessages(3);
    }).StartAsync();
```
<sup><a href='https://github.com/JasperFx/alba/blob/master/src/Samples/DocumentationSamples/ConfigureDurableLocalQueueApp.cs#L28-L36' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_configuredefaultqueue' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

## Local Message Routing

In the absence of any kind of routing rules, any message enqueued with `ICommandBus.Enqueue()` will just be handled by the
*default* local queue. To override that choice on a message type by message type basis, you can use the `[LocalQueue]` attribute
on a message type:

<!-- snippet: sample_local_queue_routed_message -->
<a id='snippet-sample_local_queue_routed_message'></a>
```cs
[LocalQueue("important")]
public class ImportanceMessage
{

}
```
<sup><a href='https://github.com/JasperFx/alba/blob/master/src/Samples/DocumentationSamples/LocalQueueMessage.cs#L5-L12' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_local_queue_routed_message' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

Otherwise, you can take advantage of Jasper's message routing rules like this:

<!-- snippet: sample_LocalTransportApp -->
<a id='snippet-sample_localtransportapp'></a>
```cs
using var host = await Host.CreateDefaultBuilder()
    .UseJasper(opts =>
    {
        // Publish Message2 messages to the "important"
        // local queue
        opts.PublishMessage<Message2>()
            .ToLocalQueue("important");
    }).StartAsync();
```
<sup><a href='https://github.com/JasperFx/alba/blob/master/src/Samples/DocumentationSamples/MessagingConfigurationExamples.cs#L104-L115' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_localtransportapp' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

The routing rules and/or `[LocalQueue]` routing is also honored for cascading messages, meaning that any message that is handled inside a Jasper system could publish cascading messages to the local worker queues.

See [message routing rules](/guide/messaging/#routing-rules) for more information.

## Durable Local Messages

The local worker queues can optionally be designated as "durable," meaning that local messages would be persisted until they can be successfully processed to provide a guarantee that the message will be successfully processed in the case of the running application faulting or having been shut down prematurely (assuming that other nodes are running or it's restarted later of course).

Here is an example of configuring a local queue to be durable:

<!-- snippet: sample_LocalDurableTransportApp -->
<a id='snippet-sample_localdurabletransportapp'></a>
```cs
using var host = await Host.CreateDefaultBuilder()
    .UseJasper(opts =>
    {
        // Make the default local queue durable
        opts.DefaultLocalQueue.DurablyPersistedLocally();

        // Or do just this by name
        opts.LocalQueue("important")
            .DurablyPersistedLocally();
    }).StartAsync();
```
<sup><a href='https://github.com/JasperFx/alba/blob/master/src/Samples/DocumentationSamples/MessagingConfigurationExamples.cs#L124-L137' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_localdurabletransportapp' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->


See [Persistent Messaging](http://localhost:5050/guide/persistence/) for more information.


## Scheduling Local Execution

:::tip
If you need the command scheduling to be persistent or be persisted across service restarts, you'll need to enable the [message persistence](/guide/persistence/) within Jasper.
:::

The "scheduled execution" feature can be used with local execution within the same application. See [Scheduled Messages](/guide/scheduled) for more information. Use the `ICommandBus.ScheduleAsync()` methods like this:
{'fraction_non_alphanumeric': 0.10067160562210067, 'fraction_numerical': 0.004431212352004431, 'mean_word_length': 4.993360995850622, 'pattern_counts': {'":': 0, '<': 105, '<?xml version=': 0, '>': 111, 'https://': 14, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5871113', 'n_tokens_mistral': 4086, 'n_tokens_neox': 3872, 'n_words': 1438}