Skip to content
This repository was archived by the owner on Nov 20, 2020. It is now read-only.
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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ CallPolly wraps Polly to provide:

## Non-goals

- low level policy implementations should live elsewhere (see _CONTRIBUTION notes_)
- low level policy implementations should live elsewhere (see [CONTRIBUTION notes](#contribution-notes))
- the core CallPolly library faciltates, but should never bind _directly_ to any specific log or metrics emission sink

# Dependencies
Expand Down Expand Up @@ -102,4 +102,4 @@ See the [acceptance tests](https://github.com/jet/CallPolly/blob/master/tests/Ca
}

}
```
```
12 changes: 10 additions & 2 deletions build.cmd
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
dotnet pack src/CallPolly --configuration Release -o "%CD%\bin" --version-suffix CI%1
SETLOCAL
SET X=%1
SET BLD=000000%X%
SET BLD=%BLD:~-7%
if [%2]==[] (SET V=CI%BLD%) else (SET V=pr%2-%BLD%)

dotnet pack src/CallPolly --configuration Release -o "%CD%\bin" --version-suffix %V%
if ERRORLEVEL 1 (echo Error building CallPolly; exit /b 1)

dotnet test tests/CallPolly.Tests --configuration Release
if ERRORLEVEL 1 (echo Error testing CallPolly; exit /b 1)

dotnet test tests/CallPolly.Acceptance --configuration Release
if ERRORLEVEL 1 (echo Error acceptance testing CallPolly; exit /b 1)
if ERRORLEVEL 1 (echo Error acceptance testing CallPolly; exit /b 1)

ENDLOCAL
41 changes: 24 additions & 17 deletions src/CallPolly/Context.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@
open Serilog
open System

module private SerilogHelpers =
let inline kv x y = System.Collections.Generic.KeyValuePair<_,_>(x,y)
let inline lo x (*lp*) = Serilog.Events.StructureValue x
let inline ls x (*lp seq*)= Serilog.Events.SequenceValue x
let inline ld x (*lv,kvp(lv)*) = Serilog.Events.DictionaryValue x
let inline lp n v(*:lo/lv/ls/ld*) = Serilog.Events.LogEventProperty(n, v)
let inline lv (x:#obj) = Serilog.Events.ScalarValue(x)
let forContextExplicit k v (log : ILogger) =
let enrich (e : Serilog.Events.LogEvent) = e.AddPropertyIfAbsent(Serilog.Events.LogEventProperty(k, v))
log.ForContext({ new Serilog.Core.ILogEventEnricher with member __.Enrich(evt,_) = enrich evt })

module private Impl =

type Warning = { service: string; call: string; ruleText: string }
Expand All @@ -11,9 +22,9 @@ module private Impl =
let mutable current = readDefinitions ()
let ingest () =
let res = Parser.parse current
if not (List.isEmpty res.Warnings) then
let msgs = seq { for w in res.Warnings -> { service=w.serviceName; call=w.callName; ruleText = string w.unknownRule } }
log.ForContext("{count} Warnings", msgs, true).Warning("Definition had {count} unrecognized rules", List.length res.Warnings)
if not (Array.isEmpty res.Warnings) then
let msgs = seq { for w in res.Warnings -> { service=w.serviceName; call=w.callName; ruleText=string w.unknownRule } }
log.ForContext("warnings", msgs).Warning("Policy definitions had {count} unrecognized rules", res.Warnings.Length)
res
let tryReadUpdates () =
let updated = readDefinitions()
Expand All @@ -24,20 +35,16 @@ module private Impl =

ingest(),tryReadUpdates

type ServicePolicyUpdate =
{ service: string
actionUpdates: (string * CallPolly.Rules.ChangeLevel) [] }

let logChanges (log: ILogger) res =
let changes =
seq { for service, actionUpdates in res -> { service = service; actionUpdates = List.toArray actionUpdates } }
|> Seq.distinct
|> Seq.cache
log
.ForContext("dump", changes, true)
.Information("Updated {count} values for {@services}",
Seq.length changes,
seq { for x in changes -> x.service, Array.length x.actionUpdates });
open SerilogHelpers
let logChanges (log: ILogger) (res: (string*(string*Rules.ChangeLevel) list) list) =
let xs = res |> Seq.filter (function _,c -> not (List.isEmpty c)) |> Seq.sortBy (function _,c -> -List.length c) |> Seq.cache
if not (Seq.isEmpty xs) then
//.ForContext("changes", seq { for s,calls in xs do for c,change in calls -> sprintf "%s:%s:%O" s c change }, true )
let changesAsDictionary calls = ld (seq { for callname,change in calls -> kv (lv callname) (lv (string change) :> _) })
let dump = ls <| seq { for s,calls in xs -> lo [ lp "service" (lv s); lp "changes" (changesAsDictionary calls)] }
(log |> forContextExplicit "dump" dump).Information("Updated {count} values for {services}",
xs |> Seq.sumBy (function _service,changes -> changes.Length),
xs |> Seq.map (function service,changes -> kv service changes.Length))

[<NoComparison>]
type CallPolicyInternalState =
Expand Down
4 changes: 2 additions & 2 deletions src/CallPolly/Parser.fs
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,13 @@ type ParseResult(services: ParsedService[]) =
let mapped = services |> Seq.map mapService

member __.Warnings =
[ for service in services do
[| for service in services do
for call in service.calls do
for rule in call.rules do
match rule with
| ParsedRule.Unknown jo ->
yield { serviceName = service.serviceName; callName = call.callName; unknownRule = jo }
| _ -> () ]
| _ -> () |]

member __.Raw : Map<string,Map<string,ParsedRule list>> = Map.ofSeq <| seq {
for service in services ->
Expand Down
10 changes: 5 additions & 5 deletions src/CallPolly/Rules.fs
Original file line number Diff line number Diff line change
Expand Up @@ -189,22 +189,22 @@ type CallPolicy<'TConfig when 'TConfig: equality> (makeGoverner : CallConfig<'TC

/// Ingest an updated set of config values, reporting diffs, if any
member __.TryUpdate(updated : CallConfig<'TConfig>) =
let changes =
let level =
match updated.policy = cfg.policy, updated.config = cfg.config with
| true, true -> Some ChangeLevel.ConfigurationAndPolicy
| false, false -> Some ChangeLevel.ConfigurationAndPolicy
| true, false -> Some ChangeLevel.Configuration
| false, true -> Some ChangeLevel.Policy
| false, false -> None
| true, true -> None

match changes with
match level with
| Some ChangeLevel.ConfigurationAndPolicy | Some ChangeLevel.Policy ->
governor <- makeGoverner updated
cfg <- updated
| Some ChangeLevel.Configuration ->
cfg <- updated
| _ -> ()

changes
level

member __.Policy = cfg.policy
member __.Config = cfg.config
Expand Down