Skip to content

Commit

Permalink
Added MemoryCache to speed up validations.
Browse files Browse the repository at this point in the history
  • Loading branch information
ScottArbeit committed Nov 4, 2023
1 parent 62297a0 commit 828baa0
Show file tree
Hide file tree
Showing 14 changed files with 183 additions and 100 deletions.
1 change: 1 addition & 0 deletions src/Grace.Actors/Grace.Actors.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<PackageReference Include="Dapr.Client" Version="1.12.0" />
<PackageReference Include="FSharpPlus" Version="1.5.0" />
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.36.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0-rc.2.23479.6" />
<PackageReference Include="Nito.AsyncEx" Version="5.1.2" />
<PackageReference Include="NodaTime" Version="3.1.9" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.1.2" />
Expand Down
5 changes: 5 additions & 0 deletions src/Grace.Actors/Services.Actor.fs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ open Grace.Shared.Types
open Grace.Shared.Utilities
open Microsoft.Azure.Cosmos
open Microsoft.Azure.Cosmos.Linq
open Microsoft.Extensions.Caching.Memory
open Microsoft.Extensions.Logging
open System
open System.Collections.Concurrent
Expand Down Expand Up @@ -72,6 +73,10 @@ module Services =
let setLoggerFactory (factory: ILoggerFactory) =
loggerFactory <- factory

let mutable internal memoryCache: IMemoryCache = null
let setMemoryCache (cache: IMemoryCache) =
memoryCache <- cache

let linqSerializerOptions = CosmosLinqSerializerOptions(PropertyNamingPolicy = CosmosPropertyNamingPolicy.CamelCase)

/// Custom QueryRequestOptions that requests Index Metrics only in DEBUG build.
Expand Down
10 changes: 8 additions & 2 deletions src/Grace.Server/ApplicationContext.Server.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ open Grace.Shared
open Grace.Shared.Types
open Grace.Shared.Utilities
open Microsoft.Azure.Cosmos
open Microsoft.Extensions.Caching.Memory
open Microsoft.Extensions.Configuration
open Microsoft.Extensions.DependencyInjection
open Microsoft.Extensions.Logging
Expand All @@ -31,6 +32,7 @@ module ApplicationContext =
let mutable private actorProxyFactory: IActorProxyFactory = null
let mutable private actorStateStorageProvider: ActorStateStorageProvider = ActorStateStorageProvider.Unknown
let mutable loggerFactory: ILoggerFactory = null
let mutable memoryCache: IMemoryCache = null

let ActorProxyFactory() = actorProxyFactory
let ActorStateStorageProvider() = actorStateStorageProvider
Expand Down Expand Up @@ -131,7 +133,11 @@ module ApplicationContext =
let! containerResponse = database.CreateContainerIfNotExistsAsync(containerProperties)
let cosmosContainer = containerResponse.Container

// Create a MemoryCache instance.
memoryCache <- new MemoryCache(MemoryCacheOptions(), loggerFactory)

// Inject the CosmosClient and CosmosContainer into Actor Services.
Grace.Actors.Services.setCosmosClient (cosmosClient)
Grace.Actors.Services.setCosmosContainer (cosmosContainer)
Grace.Actors.Services.setCosmosClient cosmosClient
Grace.Actors.Services.setCosmosContainer cosmosContainer
Grace.Actors.Services.setMemoryCache memoryCache
} :> Task
9 changes: 5 additions & 4 deletions src/Grace.Server/Branch.Server.fs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ module Branch =

let actorProxyFactory = ApplicationContext.ActorProxyFactory()

let getActorProxy (context: HttpContext) (branchId: BranchId) =
let getActorProxy (context: HttpContext) (branchId: string) =
let actorId = ActorId($"{branchId}")
actorProxyFactory.CreateActorProxy<IBranchActor>(actorId, ActorName.Branch)

Expand All @@ -53,7 +53,7 @@ module Branch =
parameters.RepositoryId <- repositoryId
match! resolveBranchId repositoryId parameters.BranchId parameters.BranchName with
| Some branchId ->
let actorProxy = getActorProxy context (Guid.Parse(branchId))
let actorProxy = getActorProxy context branchId
let! cmd = command parameters
match! actorProxy.Handle cmd (Services.createMetadata context) with
| Ok graceReturn -> return! context |> result200Ok graceReturn
Expand Down Expand Up @@ -83,11 +83,12 @@ module Branch =
if validationsPassed then
match! resolveBranchId parameters.RepositoryId parameters.BranchId parameters.BranchName with
| Some branchId ->
let actorProxy = getActorProxy context (Guid.Parse(branchId))
let actorProxy = getActorProxy context branchId
let! queryResult = query context maxCount actorProxy
let! returnValue = context |> result200Ok (GraceReturnValue.Create queryResult (getCorrelationId context))
return returnValue
| None -> return! context |> result400BadRequest (GraceError.Create (BranchError.getErrorMessage BranchDoesNotExist) (getCorrelationId context))
| None ->
return! context |> result400BadRequest (GraceError.Create (BranchError.getErrorMessage BranchDoesNotExist) (getCorrelationId context))
else
let! error = validationResults |> getFirstError
let graceError = GraceError.Create (BranchError.getErrorMessage error) (getCorrelationId context)
Expand Down
6 changes: 3 additions & 3 deletions src/Grace.Server/Directory.Server.fs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ module DirectoryVersion =

let actorProxyFactory = ApplicationContext.ActorProxyFactory()

let getActorProxy (context: HttpContext) (directoryId: DirectoryId) =
let actorId = GetActorId directoryId
let getActorProxy (context: HttpContext) (directoryId: string) =
let actorId = ActorId(directoryId)
actorProxyFactory.CreateActorProxy<IDirectoryVersionActor>(actorId, ActorName.DirectoryVersion)

let processCommand<'T when 'T :> DirectoryParameters> (context: HttpContext) (validations: Validations<'T>) (command: 'T -> HttpContext -> Task<GraceResult<string>>) =
Expand Down Expand Up @@ -70,7 +70,7 @@ module DirectoryVersion =
let validationResults = validations parameters context
let! validationsPassed = validationResults |> allPass
if validationsPassed then
let actorProxy = getActorProxy context (Guid.Parse(parameters.DirectoryId))
let actorProxy = getActorProxy context parameters.DirectoryId
let! queryResult = query context maxCount actorProxy
let! returnValue = context |> result200Ok (GraceReturnValue.Create queryResult (getCorrelationId context))
return returnValue
Expand Down
9 changes: 5 additions & 4 deletions src/Grace.Server/Grace.Server.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
<PackageProjectUrl>https://github.com/ScottArbeit/Grace</PackageProjectUrl>
</PropertyGroup>
<ItemGroup>
<ContainerPort Include="5000" Type="tcp"/>
<ContainerPort Include="5001" Type="tcp"/>
<ContainerPort Include="50001" Type="tcp"/>
<ContainerPort Include="57256" Type="tcp"/>
<ContainerPort Include="5000" Type="tcp" />
<ContainerPort Include="5001" Type="tcp" />
<ContainerPort Include="50001" Type="tcp" />
<ContainerPort Include="57256" Type="tcp" />
</ItemGroup>
<ItemGroup>
<Compile Include="CosmosSystemTextJsonSerializer.Server.fs" />
Expand Down Expand Up @@ -63,6 +63,7 @@
<PackageReference Include="Dapr.Actors.AspNetCore" Version="1.12.0" />
<PackageReference Include="Dapr.Extensions.Configuration" Version="1.12.0" />
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.36.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0-rc.2.23479.6" />
<!--<PackageReference Include="Microsoft.Extensions.ApiDescription.Server" Version="7.0.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
29 changes: 15 additions & 14 deletions src/Grace.Server/Organization.Server.fs
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,14 @@ module Organization =
let validationResults = validations parameters context
let! validationsPassed = validationResults |> allPass
if validationsPassed then
let actorProxy = getActorProxy context parameters.OrganizationId
let! exists = actorProxy.Exists()
if exists then
match! resolveOrganizationId parameters.OwnerId parameters.OwnerName parameters.OrganizationId parameters.OrganizationName with
| Some organizationId ->
context.Items.Add(nameof(OrganizationId), OrganizationId organizationId)
let actorProxy = getActorProxy context organizationId
let! queryResult = query context maxCount actorProxy
return! context |> result200Ok (GraceReturnValue.Create queryResult (getCorrelationId context))
else
return! context |> result400BadRequest (GraceError.Create (OrganizationError.getErrorMessage OrganizationIdDoesNotExist) (getCorrelationId context))
| None ->
return! context |> result400BadRequest (GraceError.Create (OrganizationError.getErrorMessage OrganizationDoesNotExist) (getCorrelationId context))
else
let! error = validationResults |> getFirstError
let graceError = GraceError.Create (OrganizationError.getErrorMessage error) (getCorrelationId context)
Expand All @@ -99,7 +100,7 @@ module Organization =
String.isNotEmpty parameters.OrganizationName OrganizationNameIsRequired
String.isValidGraceName parameters.OrganizationName InvalidOrganizationName
Owner.ownerExists parameters.OwnerId parameters.OwnerName OwnerDoesNotExist
Organization.organizationIdDoesNotExist parameters.OrganizationId OrganizationIdAlreadyExists
Organization.organizationExists parameters.OwnerId parameters.OwnerName parameters.OrganizationId parameters.OrganizationName OrganizationDoesNotExist
Organization.organizationNameIsUnique parameters.OwnerId parameters.OwnerName parameters.OrganizationName OrganizationNameAlreadyExists ]

let command (parameters: CreateOrganizationParameters) =
Expand All @@ -123,7 +124,7 @@ module Organization =
String.isValidGraceName parameters.OrganizationName InvalidOrganizationName
String.isNotEmpty parameters.NewName OrganizationNameIsRequired
String.isValidGraceName parameters.NewName InvalidOrganizationName
Organization.organizationIdExists parameters.OrganizationId OrganizationIdDoesNotExist
Organization.organizationExists parameters.OwnerId parameters.OwnerName parameters.OrganizationId parameters.OrganizationName OrganizationDoesNotExist
Organization.organizationIsNotDeleted parameters.OwnerId parameters.OwnerName parameters.OrganizationId parameters.OrganizationName OrganizationIsDeleted ]

let command (parameters: SetOrganizationNameParameters) =
Expand All @@ -142,7 +143,7 @@ module Organization =
String.isValidGraceName parameters.OrganizationName InvalidOrganizationName
String.isNotEmpty parameters.OrganizationType OrganizationTypeIsRequired
DiscriminatedUnion.isMemberOf<OrganizationType, OrganizationError> parameters.OrganizationType InvalidOrganizationType
Organization.organizationIdExists parameters.OrganizationId OrganizationIdDoesNotExist
Organization.organizationExists parameters.OwnerId parameters.OwnerName parameters.OrganizationId parameters.OrganizationName OrganizationDoesNotExist
Organization.organizationIsNotDeleted parameters.OwnerId parameters.OwnerName parameters.OrganizationId parameters.OrganizationName OrganizationIsDeleted ]

let command (parameters: SetOrganizationTypeParameters) = OrganizationCommand.SetType (Utilities.discriminatedUnionFromString<OrganizationType>(parameters.OrganizationType).Value) |> returnTask
Expand All @@ -160,7 +161,7 @@ module Organization =
String.isValidGraceName parameters.OrganizationName InvalidOrganizationName
String.isNotEmpty parameters.SearchVisibility SearchVisibilityIsRequired
DiscriminatedUnion.isMemberOf<SearchVisibility, OrganizationError> parameters.SearchVisibility InvalidSearchVisibility
Organization.organizationIdExists parameters.OrganizationId OrganizationIdDoesNotExist
Organization.organizationExists parameters.OwnerId parameters.OwnerName parameters.OrganizationId parameters.OrganizationName OrganizationDoesNotExist
Organization.organizationIsNotDeleted parameters.OwnerId parameters.OwnerName parameters.OrganizationId parameters.OrganizationName OrganizationIsDeleted ]

let command (parameters: SetOrganizationSearchVisibilityParameters) =
Expand All @@ -177,7 +178,7 @@ module Organization =
[ String.isNotEmpty parameters.OrganizationId OrganizationIdIsRequired
Guid.isValidAndNotEmpty parameters.OrganizationId InvalidOrganizationId
String.isNotEmpty parameters.Description OrganizationDescriptionIsRequired
Organization.organizationIdExists parameters.OrganizationId OrganizationIdDoesNotExist
Organization.organizationExists parameters.OwnerId parameters.OwnerName parameters.OrganizationId parameters.OrganizationName OrganizationDoesNotExist
Organization.organizationIsNotDeleted parameters.OwnerId parameters.OwnerName parameters.OrganizationId parameters.OrganizationName OrganizationIsDeleted ]

let command (parameters: SetOrganizationDescriptionParameters) = OrganizationCommand.SetDescription(parameters.Description) |> returnTask
Expand All @@ -194,7 +195,7 @@ module Organization =
[ String.isNotEmpty parameters.OrganizationId OrganizationIdIsRequired
Guid.isValidAndNotEmpty parameters.OrganizationId InvalidOrganizationId
String.isValidGraceName parameters.OrganizationName InvalidOrganizationName
Organization.organizationIdExists parameters.OrganizationId OrganizationIdDoesNotExist
Organization.organizationExists parameters.OwnerId parameters.OwnerName parameters.OrganizationId parameters.OrganizationName OrganizationDoesNotExist
Organization.organizationIsNotDeleted parameters.OwnerId parameters.OwnerName parameters.OrganizationId parameters.OrganizationName OrganizationIsDeleted ]

let query (context: HttpContext) (maxCount: int) (actorProxy: IOrganizationActor) =
Expand All @@ -218,7 +219,7 @@ module Organization =
Guid.isValidAndNotEmpty parameters.OrganizationId InvalidOrganizationId
String.isValidGraceName parameters.OrganizationName InvalidOrganizationName
String.isNotEmpty parameters.DeleteReason DeleteReasonIsRequired
Organization.organizationIdExists parameters.OrganizationId OrganizationIdDoesNotExist
Organization.organizationExists parameters.OwnerId parameters.OwnerName parameters.OrganizationId parameters.OrganizationName OrganizationDoesNotExist
Organization.organizationIsNotDeleted parameters.OwnerId parameters.OwnerName parameters.OrganizationId parameters.OrganizationName OrganizationIsDeleted ]

let command (parameters: DeleteOrganizationParameters) = OrganizationCommand.DeleteLogical (parameters.Force, parameters.DeleteReason) |> returnTask
Expand All @@ -235,7 +236,7 @@ module Organization =
Guid.isValidAndNotEmpty parameters.OrganizationId InvalidOrganizationId
String.isValidGraceName parameters.OrganizationName InvalidOrganizationName
Input.eitherIdOrNameMustBeProvided parameters.OrganizationId parameters.OrganizationName EitherOrganizationIdOrOrganizationNameRequired
Organization.organizationIdExists parameters.OrganizationId OrganizationIdDoesNotExist
Organization.organizationExists parameters.OwnerId parameters.OwnerName parameters.OrganizationId parameters.OrganizationName OrganizationDoesNotExist
Organization.organizationIsDeleted parameters.OwnerId parameters.OwnerName parameters.OrganizationId parameters.OrganizationName OrganizationIsNotDeleted ]

let command (parameters: OrganizationParameters) = OrganizationCommand.Undelete |> returnTask
Expand All @@ -256,7 +257,7 @@ module Organization =
String.isNotEmpty parameters.OrganizationId OrganizationIdIsRequired
Guid.isValidAndNotEmpty parameters.OrganizationId InvalidOrganizationId
String.isValidGraceName parameters.OrganizationName InvalidOrganizationName
Organization.organizationIdExists parameters.OrganizationId OrganizationIdDoesNotExist
Organization.organizationExists parameters.OwnerId parameters.OwnerName parameters.OrganizationId parameters.OrganizationName OrganizationDoesNotExist
Organization.organizationIsNotDeleted parameters.OwnerId parameters.OwnerName parameters.OrganizationId parameters.OrganizationName OrganizationIsDeleted ]

let query (context: HttpContext) (maxCount: int) (actorProxy: IOrganizationActor) =
Expand Down
12 changes: 4 additions & 8 deletions src/Grace.Server/Owner.Server.fs
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,12 @@ module Owner =
let validationResults = validations parameters context
let! validationsPassed = validationResults |> allPass
if validationsPassed then
let! ownerId = resolveOwnerId parameters.OwnerId parameters.OwnerName
match ownerId with
match! resolveOwnerId parameters.OwnerId parameters.OwnerName with
| Some ownerId ->
context.Items.Add(nameof(OwnerId), OwnerId ownerId)
let actorProxy = getActorProxy context ownerId
let! exists = actorProxy.Exists()
if exists then
let! queryResult = query context maxCount actorProxy
return! context |> result200Ok (GraceReturnValue.Create queryResult (getCorrelationId context))
else
return! context |> result400BadRequest (GraceError.Create (OwnerError.getErrorMessage OwnerIdDoesNotExist) (getCorrelationId context))
let! queryResult = query context maxCount actorProxy
return! context |> result200Ok (GraceReturnValue.Create queryResult (getCorrelationId context))
| None ->
return! context |> result400BadRequest (GraceError.Create (OwnerError.getErrorMessage OwnerDoesNotExist) (getCorrelationId context))
else
Expand Down
5 changes: 5 additions & 0 deletions src/Grace.Server/Program.Server.fs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ open System.Threading.Tasks
open System.Net
open Grace.Shared.Utilities
open Microsoft.Extensions.Logging
open ApplicationContext
open Microsoft.Extensions.Caching.Memory

module Program =
let createHostBuilder (args: string[]) : IHostBuilder =
Expand Down Expand Up @@ -50,8 +52,11 @@ module Program =
files |> Seq.iter (fun file -> logToConsole $"{file.Name}: {file.Length} bytes")
logToConsole "-----------------------------------------------------------"
let host = createHostBuilder(args).Build()

// Just placing some much-used services into the ApplicationContext where they're easy to find.
let loggerFactory = host.Services.GetService(typeof<ILoggerFactory>) :?> ILoggerFactory
ApplicationContext.setLoggerFactory(loggerFactory)

host.Run()

0 // Exit code
Loading

0 comments on commit 828baa0

Please sign in to comment.