Skip to content
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
16 changes: 15 additions & 1 deletion doc/dev/doc/extensions/caching.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,18 @@ With these declarations, the Hazelcast cache implementation would be injected in

## Cache Functionality

Hazelcast's implementation of `IDistributedCache` supports all functionality of the interface. Note however that, due to the inherently asynchronous nature of the Hazelcast client, all synchronous cache operations have to be implemented over asynchronous operations using the `task.GetAwaiter().GetResult()` pattern. This pattern can cause potential threading problems, and should be avoided as much as possible. Always use the asynchronous API wherever possible.
Hazelcast's implementation of `IDistributedCache` supports all functionality of the interface. Note however that, due to the inherently asynchronous nature of the Hazelcast client, all synchronous cache operations have to be implemented over asynchronous operations using the `task.GetAwaiter().GetResult()` pattern. This pattern can cause potential threading problems, and should be avoided as much as possible. Always use the asynchronous API wherever possible.

## ASP.NET Core Session State Provider
`IDistributedCache` implementation can be used to store session state in Hazelcast. After registering
Hazelcast `IDistributedCache` implementation to DI (as described above) you can enabled session state management
in your ASP.NET Core project.

```csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHazelcastCache();
var app = builder.Build();
app.UseSession(); // Session state will be stored in distributed cache provided by AddHazelcastCache()
```
> [!WARNING]
> When the ISession object is supported by the Hazelcast client, its synchronous operations should be avoided, as the Hazelcast client is fully asynchronous and therefore calls to task.GetAwaiter().GetResult() may be involved and, potentially, cause threading issues. Prefer the asynchronous operations, such as those provided in the SessionExtensions class.
2 changes: 2 additions & 0 deletions src/Hazelcast.Net.Caching/Hazelcast.Net.Caching.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
Expand Down
68 changes: 68 additions & 0 deletions src/Hazelcast.Net.Caching/Session/SessionExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (c) 2008-2022, Hazelcast, Inc. All Rights Reserved.
//
// Licensed 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.

using System.Threading;
using System.Threading.Tasks;
using Hazelcast.Core;
using Microsoft.AspNetCore.Http;

namespace Hazelcast.Caching.Session;

/// <summary>
/// This class wraps ISession extensions in the Microsoft.AspNetCore.Http.Extensions with LoadAsync call.
/// </summary>
public static class SessionExtensions
{
/// <summary>
/// Gets a string value from <see cref="ISession"/>.
/// </summary>
/// <remarks>It loads the session as async. It is strongly advised to use async extensions over Hazelcast distributed
/// cache implementation.</remarks>
/// <param name="session">The <see cref="ISession"/>.</param>
/// <param name="key">The key to read.</param>
/// /// <param name="token">Cancellation Token</param>
public static async Task<string?> GetStringAsync(this ISession session, string key, CancellationToken token = default)
{
await session.LoadAsync(token).CfAwait();
return session.GetString(key);
}

/// <summary>
/// Gets an int value from <see cref="ISession"/>.
/// <remarks>It loads the session as async. It is strongly advised to use async extensions over Hazelcast distributed
/// cache implementation.</remarks>
/// </summary>
/// <param name="session">The <see cref="ISession"/>.</param>
/// <param name="key">The key to read.</param>
/// <param name="token">Cancellation Token</param>
public static async Task<int?> GetInt32Async(this ISession session, string key, CancellationToken token = default)
{
await session.LoadAsync(token).CfAwait();
return session.GetInt32(key);
}

/// <summary>
/// Gets a byte-array value from <see cref="ISession"/>.
/// <remarks>It loads the session as async. It is strongly advised to use async extensions over Hazelcast distributed
/// cache implementation.</remarks>
/// </summary>
/// <param name="session">The <see cref="ISession"/>.</param>
/// <param name="key">The key to read.</param>
/// <param name="token">Cancellation Token</param>
public static async Task<byte[]?> GetAsync(this ISession session, string key, CancellationToken token = default)
{
await session.LoadAsync(token).CfAwait();
return session.Get(key);
}
}