Skip to content

Update Distributed cache topic+sample #9129

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 6 commits into from
Oct 24, 2018
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
6 changes: 3 additions & 3 deletions aspnetcore/fundamentals/app-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Session state exhibits the following behaviors:

The in-memory cache provider stores session data in the memory of the server where the app resides. In a server farm scenario:

* Use *sticky sessions* to tie each session to a specific app instance on an individual server. [Azure App Service](https://azure.microsoft.com/services/app-service/) uses [Application Request Routing (ARR)](/iis/extensions/planning-for-arr/using-the-application-request-routing-module) to enforce sticky sessions by default. However, sticky sessions can affect scalability and complicate web app updates. A better approach is to use a Redis or SQL Server distributed cache, which doesn't require sticky sessions. For more information, see [Work with a distributed cache](xref:performance/caching/distributed).
* Use *sticky sessions* to tie each session to a specific app instance on an individual server. [Azure App Service](https://azure.microsoft.com/services/app-service/) uses [Application Request Routing (ARR)](/iis/extensions/planning-for-arr/using-the-application-request-routing-module) to enforce sticky sessions by default. However, sticky sessions can affect scalability and complicate web app updates. A better approach is to use a Redis or SQL Server distributed cache, which doesn't require sticky sessions. For more information, see <xref:performance/caching/distributed>.
* The session cookie is encrypted via [IDataProtector](/dotnet/api/microsoft.aspnetcore.dataprotection.idataprotector). Data Protection must be properly configured to read session cookies on each machine. For more information, see [Data Protection in ASP.NET Core](xref:security/data-protection/index) and [Key storage providers](xref:security/data-protection/implementation/key-storage-providers).

### Configure session state
Expand All @@ -81,7 +81,7 @@ The [Microsoft.AspNetCore.Session](https://www.nuget.org/packages/Microsoft.AspN

::: moniker-end

* Any of the [IDistributedCache](/dotnet/api/microsoft.extensions.caching.distributed.idistributedcache) memory caches. The `IDistributedCache` implementation is used as a backing store for session. For more information, see [Work with a distributed cache](xref:performance/caching/distributed).
* Any of the [IDistributedCache](/dotnet/api/microsoft.extensions.caching.distributed.idistributedcache) memory caches. The `IDistributedCache` implementation is used as a backing store for session. For more information, see <xref:performance/caching/distributed>.
* A call to [AddSession](/dotnet/api/microsoft.extensions.dependencyinjection.sessionservicecollectionextensions.addsession) in `ConfigureServices`.
* A call to [UseSession](/dotnet/api/microsoft.aspnetcore.builder.sessionmiddlewareextensions#methods_) in `Configure`.

Expand Down Expand Up @@ -428,7 +428,7 @@ Use [Dependency Injection](xref:fundamentals/dependency-injection) to make data

* "Unable to resolve service for type 'Microsoft.Extensions.Caching.Distributed.IDistributedCache' while attempting to activate 'Microsoft.AspNetCore.Session.DistributedSessionStore'."

This is usually caused by failing to configure at least one `IDistributedCache` implementation. For more information, see [Work with a distributed cache](xref:performance/caching/distributed) and [Cache in-memory](xref:performance/caching/memory).
This is usually caused by failing to configure at least one `IDistributedCache` implementation. For more information, see <xref:performance/caching/distributed> and <xref:performance/caching/memory>.

* In the event that the session middleware fails to persist a session (for example, if the backing store isn't available), the middleware logs the exception and the request continues normally. This leads to unpredictable behavior.

Expand Down
12 changes: 6 additions & 6 deletions aspnetcore/fundamentals/change-tokens.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,9 @@ var compositeChangeToken =

## Additional resources

* [Cache in-memory](xref:performance/caching/memory)
* [Work with a distributed cache](xref:performance/caching/distributed)
* [Response caching](xref:performance/caching/response)
* [Response Caching Middleware](xref:performance/caching/middleware)
* [Cache Tag Helper](xref:mvc/views/tag-helpers/builtin-th/cache-tag-helper)
* [Distributed Cache Tag Helper](xref:mvc/views/tag-helpers/builtin-th/distributed-cache-tag-helper)
* <xref:performance/caching/memory>
* <xref:performance/caching/distributed>
* <xref:performance/caching/response>
* <xref:performance/caching/middleware>
* <xref:mvc/views/tag-helpers/builtin-th/cache-tag-helper>
* <xref:mvc/views/tag-helpers/builtin-th/distributed-cache-tag-helper>
177 changes: 109 additions & 68 deletions aspnetcore/performance/caching/distributed.md

Large diffs are not rendered by default.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@page
@model ErrorModel
@{
ViewData["Title"] = "Error";
}

<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>

@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}

<h3>Development Mode</h3>
<p>
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications</strong>. It can result in displaying sensitive information from exceptions to end users. For local debugging, enable the Development environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong> and restarting the app or adding <code>.UseEnvironment("Development")</code> to <code>WebHost</code> in <i>Program.cs</i> and restarting the app.
</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace SampleApp.Pages
{
public class ErrorModel : PageModel
{
public string RequestId { get; set; }

public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
@page
@model IndexModel
@{
ViewData["Title"] = "Distributed Cache Sample";
}

<h1>@ViewData["Title"]</h1>

<form method="post">
<div class="panel panel-default">
<div class="panel-heading clearfix">
<button type="submit" asp-page-handler="ResetCachedTime" class="pull-right btn btn-danger">Reset Cached Time</button>
<h3 class="panel-title" style="line-height:2.1">Cached Time (UTC)</h3>
</div>
<div class="panel-body">
<p>The current time is: @DateTime.UtcNow.ToString()</p>
<p>The cached time is: @Model.CachedTimeUTC</p>
</div>
</div>
</form>

<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Instructions</h3>
</div>
<div class="panel-body">
<p>When the app starts, the current time is cached (key = <code>cachedTimeUTC</code>) with a 20 second sliding expiration.</p>
<p>Each time this page is loaded, the cache is checked for the cached time. If the cached time hasn't expired, the time is displayed.</p>
<p>If 20 seconds have elapsed since the last time the cached time was accessed (the last time this page was loaded), the page displays <code>Cached Time Expired</code>.</p>
<p>The cached time can be updated immediately to the current time by selecting the <b>Reset Cached Time</b> button.</p>
<p>In the Development environment, the sample uses the Distributed Memory Cache and doesn't require an external cache service.</p>
<h4>Distributed SQL Server Cache</h4>
<p>To activate the sample to use a Distributed SQL Server Cache:</p>
<ol>
<li>Create a SQL Server database. The sample specifies <code>DistCache</code> in the <code>DistCache_ConnectionString</code> in the <em>appsettings.Production.json</em> file.</li>
<li>Create a table to hold cached values. The sample specifies <code>TestCache</code> in <code>Startup.ConfigureServices</code> where <code>AddDistributedSqlServerCache</code> is called to register distributed caching services. The schema (<code>dbo</code>) is also set.</li>
<li>Update the <code>DistCache_ConnectionString</code> in the <em>appsettings.Production.json</em> file to point to the SQL Server instance, database, and table. If you use the default database name, schema, and table name, you only need to update the SQL Server instance (<code>(localdb)\\MSSQLLocalDB</code>).</li>
<li>Set the <code>ASPNETCORE_ENVIRONMENT</code> environment variable to <code>Production</code>. In the Production environment, the app uses the Distributed SQL Server Cache when it starts.</li>
</ol>
<h4>Distributed Redis Cache</h4>
<p>This sample can be changed to use a Distributed Redis Cache:</p>
<ol>
<li>
Swap the Distributed SQL Server Cache service registration (<code>AddDistributedSqlServerCache</code>) in <code>Startup.ConfigureServices</code> with Redis service registrations:
<pre><code>services.AddDistributedRedisCache(options =>
{
options.Configuration = "localhost";
options.InstanceName = "SampleInstance";
});</code></pre>
</li>
<li>Install Redis on your local machine: Install the <a href="https://chocolatey.org/packages/redis-64/">Redis Chocolatey package</a> and run <code>redis-server</code> from a command prompt.</li>
<li>Set the <code>ASPNETCORE_ENVIRONMENT</code> environment variable to <code>Production</code>. In the Production environment, the app uses the Distributed Redis Cache when it starts.</li>
</ol>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using System.Text;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Caching.Distributed;

namespace SampleApp.Pages
{
#region snippet_IndexModel
public class IndexModel : PageModel
{
private readonly IDistributedCache _cache;

public IndexModel(IDistributedCache cache)
{
_cache = cache;
}

public string CachedTimeUTC { get; set; }

public async Task OnGetAsync()
{
CachedTimeUTC = "Cached Time Expired";
var encodedCachedTimeUTC = await _cache.GetAsync("cachedTimeUTC");

if (encodedCachedTimeUTC != null)
{
CachedTimeUTC = Encoding.UTF8.GetString(encodedCachedTimeUTC);
}
}

public async Task<IActionResult> OnPostResetCachedTime()
{
var currentTimeUTC = DateTime.UtcNow.ToString();
byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);
var options = new DistributedCacheEntryOptions()
.SetSlidingExpiration(TimeSpan.FromSeconds(20));
await _cache.SetAsync("cachedTimeUTC", encodedCurrentTimeUTC, options);

return RedirectToPage();
}
}
#endregion
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
@using Microsoft.AspNetCore.Http.Features

@{
var consentFeature = Context.Features.Get<ITrackingConsentFeature>();
var showBanner = !consentFeature?.CanTrack ?? false;
var cookieString = consentFeature?.CreateConsentCookie();
}

@if (showBanner)
{
<nav id="cookieConsent" class="navbar navbar-default navbar-fixed-top" role="alert">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#cookieConsent .navbar-collapse">
<span class="sr-only">Toggle cookie consent banner</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<span class="navbar-brand"><span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span></span>
</div>
<div class="collapse navbar-collapse">
<p class="navbar-text">
Use this space to summarize your privacy and cookie use policy.
</p>
<div class="navbar-right">
<a asp-page="/Privacy" class="btn btn-info navbar-btn">Learn More</a>
<button type="button" class="btn btn-default navbar-btn" data-cookie-string="@cookieString">Accept</button>
</div>
</div>
</div>
</nav>
<script>
(function () {
document.querySelector("#cookieConsent button[data-cookie-string]").addEventListener("click", function (el) {
document.cookie = el.target.dataset.cookieString;
document.querySelector("#cookieConsent").classList.add("hidden");
}, false);
})();
</script>
}
Loading