Skip to content

Commit

Permalink
wip: start adding a cache sample
Browse files Browse the repository at this point in the history
  • Loading branch information
64J0 committed Aug 30, 2023
1 parent 8b505d0 commit 1ea8dfe
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 11 deletions.
37 changes: 26 additions & 11 deletions Giraffe.sln
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,19 @@ EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "EndpointRoutingApp", "samples\EndpointRoutingApp\EndpointRoutingApp.fsproj", "{0E15F922-7A44-4116-9DAB-FAEB94392FEC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_root", "_root", "{FADD8661-7ADD-42BA-B3BF-F8C8DB70BE00}"
ProjectSection(SolutionItems) = preProject
SECURITY.md = SECURITY.md
RELEASE_NOTES.md = RELEASE_NOTES.md
README.md = README.md
NuGet.config = NuGet.config
LICENSE = LICENSE
giraffe.png = giraffe.png
CODE_OF_CONDUCT.md = CODE_OF_CONDUCT.md
DOCUMENTATION.md = DOCUMENTATION.md
giraffe-64x64.png = giraffe-64x64.png
EndProjectSection
ProjectSection(SolutionItems) = preProject
SECURITY.md = SECURITY.md
RELEASE_NOTES.md = RELEASE_NOTES.md
README.md = README.md
NuGet.config = NuGet.config
LICENSE = LICENSE
giraffe.png = giraffe.png
CODE_OF_CONDUCT.md = CODE_OF_CONDUCT.md
DOCUMENTATION.md = DOCUMENTATION.md
giraffe-64x64.png = giraffe-64x64.png
EndProjectSection
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "ResponseCachingApp", "samples\ResponseCachingApp\ResponseCachingApp.fsproj", "{FA102AC4-4608-42F9-86C1-1472B416A76E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -76,6 +78,18 @@ Global
{0E15F922-7A44-4116-9DAB-FAEB94392FEC}.Release|x64.Build.0 = Release|Any CPU
{0E15F922-7A44-4116-9DAB-FAEB94392FEC}.Release|x86.ActiveCfg = Release|Any CPU
{0E15F922-7A44-4116-9DAB-FAEB94392FEC}.Release|x86.Build.0 = Release|Any CPU
{FA102AC4-4608-42F9-86C1-1472B416A76E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FA102AC4-4608-42F9-86C1-1472B416A76E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FA102AC4-4608-42F9-86C1-1472B416A76E}.Debug|x64.ActiveCfg = Debug|Any CPU
{FA102AC4-4608-42F9-86C1-1472B416A76E}.Debug|x64.Build.0 = Debug|Any CPU
{FA102AC4-4608-42F9-86C1-1472B416A76E}.Debug|x86.ActiveCfg = Debug|Any CPU
{FA102AC4-4608-42F9-86C1-1472B416A76E}.Debug|x86.Build.0 = Debug|Any CPU
{FA102AC4-4608-42F9-86C1-1472B416A76E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FA102AC4-4608-42F9-86C1-1472B416A76E}.Release|Any CPU.Build.0 = Release|Any CPU
{FA102AC4-4608-42F9-86C1-1472B416A76E}.Release|x64.ActiveCfg = Release|Any CPU
{FA102AC4-4608-42F9-86C1-1472B416A76E}.Release|x64.Build.0 = Release|Any CPU
{FA102AC4-4608-42F9-86C1-1472B416A76E}.Release|x86.ActiveCfg = Release|Any CPU
{FA102AC4-4608-42F9-86C1-1472B416A76E}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -88,5 +102,6 @@ Global
{1B876F13-39D0-4A44-9A63-A768AFB6E17A} = {01222765-17F4-456D-B79E-EC106C20861A}
{B9B26DDC-608C-42FE-9AB9-6CF0EE4920CD} = {9E6451FB-26E0-4AE4-A469-847F9602E999}
{0E15F922-7A44-4116-9DAB-FAEB94392FEC} = {B9B26DDC-608C-42FE-9AB9-6CF0EE4920CD}
{FA102AC4-4608-42F9-86C1-1472B416A76E} = {9E6451FB-26E0-4AE4-A469-847F9602E999}
EndGlobalSection
EndGlobal
62 changes: 62 additions & 0 deletions samples/ResponseCachingApp/Program.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
open System
open Microsoft.AspNetCore.Builder
open Microsoft.AspNetCore.Http
open Microsoft.Extensions.DependencyInjection
open Microsoft.Extensions.Hosting
open Giraffe
open Giraffe.EndpointRouting

let expensiveOperation () : DateTime =
let fiveSeconds = 5000 // ms
Threading.Thread.Sleep fiveSeconds
DateTime.Now

let dateTimeHandler : HttpHandler =
fun (_next : HttpFunc) (ctx : HttpContext) ->
let now = expensiveOperation ()
ctx.WriteTextAsync $"Hello World -> DateTime: {now}"

let endpoints: Endpoint list =
[
subRoute "/cached" [
GET [
route "/public" (publicResponseCaching 30 None >=> dateTimeHandler)
route "/private" (privateResponseCaching 30 None >=> dateTimeHandler)
route "/not" (noResponseCaching >=> dateTimeHandler)
]
]
]

let notFoundHandler =
"Not Found"
|> text
|> RequestErrors.notFound

let configureServices (services : IServiceCollection) =
services
.AddRouting()
.AddResponseCaching()
.AddGiraffe()
|> ignore

let configureApp (appBuilder : IApplicationBuilder) =
appBuilder
.UseRouting()
.UseResponseCaching()
.UseEndpoints(fun e -> e.MapGiraffeEndpoints(endpoints))
.UseGiraffe(notFoundHandler)

[<EntryPoint>]
let main args =
let builder = WebApplication.CreateBuilder(args)
configureServices builder.Services

let app = builder.Build()

if app.Environment.IsDevelopment() then
app.UseDeveloperExceptionPage() |> ignore

configureApp app
app.Run()

0
70 changes: 70 additions & 0 deletions samples/ResponseCachingApp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Response Caching App

The purpose of this sample is to show how one can configure the Giraffe server to use the ASP.NET [response caching](https://learn.microsoft.com/en-us/aspnet/core/performance/caching/response?view=aspnetcore-7.0) feature. Notice that we're leveraging the middlewares which are offered by Giraffe.

You can find their documentation here: [Giraffe Docs - Response Caching](https://giraffe.wiki/docs#response-caching).

## How to test

First, start the server at the terminal using:

```bash
# Assuming that you're at the top level of this repository
dotnet run --project samples/ResponseCachingApp/

# It will start the server listening to port 5000
```

Now, you can use the `test-run.sh` script (Linux):

```bash
# Add execution permission to the script
chmod +x samples/ResponseCachingApp/test-run.sh

./samples/ResponseCachingApp/test-run.sh
```

And the expected result:

```bash
# -----------------------------------
# Testing the /cached/not endpoint

# Hello World -> DateTime: 8/29/2023 8:00:28 PM
# Hello World -> DateTime: 8/29/2023 8:00:34 PM
# Hello World -> DateTime: 8/29/2023 8:00:40 PM
# Hello World -> DateTime: 8/29/2023 8:00:46 PM
# Hello World -> DateTime: 8/29/2023 8:00:52 PM

# real 0m30,126s
# user 0m0,063s
# sys 0m0,052s
# -----------------------------------
# Testing the /cached/public endpoint

# Hello World -> DateTime: 8/29/2023 8:00:58 PM
# Hello World -> DateTime: 8/29/2023 8:00:58 PM
# Hello World -> DateTime: 8/29/2023 8:00:58 PM
# Hello World -> DateTime: 8/29/2023 8:00:58 PM
# Hello World -> DateTime: 8/29/2023 8:00:58 PM

# real 0m10,072s
# user 0m0,025s
# sys 0m0,040s
# -----------------------------------
# Testing the /cached/private endpoint

# Hello World -> DateTime: 8/29/2023 8:01:09 PM
# Hello World -> DateTime: 8/29/2023 8:01:15 PM
# Hello World -> DateTime: 8/29/2023 8:01:21 PM
# Hello World -> DateTime: 8/29/2023 8:01:27 PM
# Hello World -> DateTime: 8/29/2023 8:01:33 PM

# real 0m30,120s
# user 0m0,052s
# sys 0m0,060s
```

Notice that at this example, the cache worked only for the `/cached/public` endpoint, as expected. You can read the documentation presented before to understand why.

One last information, notice that the server will inform whenever the response was cached or not, just check the logs.
16 changes: 16 additions & 0 deletions samples/ResponseCachingApp/ResponseCachingApp.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="../../src/Giraffe/Giraffe.fsproj" />
</ItemGroup>

</Project>
51 changes: 51 additions & 0 deletions samples/ResponseCachingApp/test-run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/bin/bash

set -euo pipefail

# ==============================================
# Warning:
#
# Make sure that the server is already running in a different terminal.

function test_not_cached {
for counter in {1..5}
do
curl localhost:5000/cached/not
echo
sleep 1
done
}

function test_public_cached {
for counter in {1..5}
do
curl localhost:5000/cached/public
echo
sleep 1
done
}

function test_private_cached {
for counter in {1..5}
do
curl localhost:5000/cached/private
echo
sleep 1
done
}

echo "-----------------------------------"
echo "Testing the /cached/not endpoint"
echo
time test_not_cached


echo "-----------------------------------"
echo "Testing the /cached/public endpoint"
echo
time test_public_cached

echo "-----------------------------------"
echo "Testing the /cached/private endpoint"
echo
time test_private_cached

0 comments on commit 1ea8dfe

Please sign in to comment.