// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License.  You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
= Asynchronous APIs

== Overview

Many Ignite APIs have asynchronous variants, for example, `void ICache.Put` and `Task ICache.PutAsync`.
Async APIs allow us to write link:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/[efficient non-blocking code]:

[source,csharp]
----
ICache<int, string> cache = ignite.GetOrCreateCache<int, string>("name");

// Sync, blocks thread on every call.
cache.Put(1, "Hello");
string hello = cache.Get(1);

// Async, does not block threads.
await cache.PutAsync(1, "Hello");
string hello = await cache.GetAsync(1);
----

With async APIs, current thread is not blocked while we wait for the cache operation to complete;
the thread is returned to the thread pool and can perform other work.

When the async operation completes, our method resumes execution - either on the same thread, or on a different one -
depending on the environment and the configuration. This is called "async continuation".


== Async Continuations

Unless specified otherwise, Ignite executes async continuations on the link:https://docs.microsoft.com/en-us/dotnet/standard/threading/the-managed-thread-pool[.NET Thread Pool], which is safe and does not require any special care.


=== Thin Client

All thin client async APIs use link:https://docs.microsoft.com/en-us/dotnet/standard/threading/the-managed-thread-pool[.NET Thread Pool.] for async continuations.

=== Thick Cache

Callbacks for asynchronous cache operations on server and thick client nodes are invoked by using Java `ForkJoinPool#commonPool`, unless a different executor is configured with `IgniteConfiguration.AsyncContinuationExecutor`.

* This default executor is safe for any operations inside the callback.
* Default behavior was changed in Ignite 2.11. Before that, async cache operation callbacks were called from an Ignite system pool (so-called "striped pool").
* To restore the previous behavior, use `IgniteConfiguration.AsyncContinuationExecutor = AsyncContinuationExecutor.UnsafeSynchronous`.
** Previous behavior can provide a small performance improvement, because callbacks are executed without any indirection or scheduling.
** UNSAFE: cache operations cannot proceed while system threads execute callbacks, and deadlocks are possible if other cache operations are invoked from the callback.

[IMPORTANT]
====
[discrete]
=== *Ignite 2.10 and before*: possibility of deadlocks and system pool starvation

In Ignite versions 2.10 and before, system pool is used to run async continuations,
which means that `GetAsync` call in the code above is executed by the system thread.

This can lead to deadlocks if user code blocks the thread, or cause starvation because system thread is busy
running user code instead of performing cache operations.

To enable safe behavior, move continuations to .NET Thread Pool manually:

[source,csharp]
----
await cache.PutAsync(1, "Hello").ContinueWith(
                t => {},
                CancellationToken.None,
                TaskContinuationOptions.None,
                TaskScheduler.Default);

string hello = await cache.GetAsync(1).ContinueWith(
                t => t.Result,
                CancellationToken.None,
                TaskContinuationOptions.None,
                TaskScheduler.Default);
----

Tip: use an extension method to reduce verbosity.

====


=== Compute

*Ignite 2.11 and later*: all `ICompute` async APIs use .NET Thread Pool to run async continuations.

*Ignite 2.10 and before*: Compute async continuations are executed on link:perf-and-troubleshooting/thread-pools-tuning[Ignite public pool].
To reduce the load on the public pool, it is recommended to use the same `ContinueWith` approach as above:

[source,csharp]
----
await compute.CallAsync(new MyAction()).ContinueWith(
                t => t.Result,
                CancellationToken.None,
                TaskContinuationOptions.None,
                TaskScheduler.Default);
----

This will move the continuation from Ignite public pool (reserved for Compute functionality) to the .NET thread pool (`TaskScheduler.Default`).


== ConfigureAwait

`Task.ConfigureAwait` method can be used as usual with all Ignite async APIs.

See link:https://devblogs.microsoft.com/dotnet/configureawait-faq/[ConfigureAwait FAQ] for more details.




