Closed ktoso closed 3 years ago
over much nicer and clearer. some clarification question and feedback inline.
Other than my latest comment, I think I'm on board with this PR 💯
Thank you for your time and reviews @Mordil !
Thank you everyone on this PR and privately and internally for the feedback, I really feel we're on the last few adjustments to the API and we'll be able to call if final!
Changes in this batch:
background
is now topLevel
, and I really like it; it is "weird enough" to look bad if used in line randomly (it's supposed to look bad) and conveys enough good meaning: https://github.com/slashmo/gsoc-swift-baggage-context/pull/34/commits/38374be1d4edfb11e384ab3d9d02a3d6039eab68This has large (good for applications which log a lot) performance implications which can be seen here (and in the benchmarks added in https://github.com/slashmo/gsoc-swift-baggage-context/pull/34/commits/f0f91b7ae22f38fcc99ebd164724d7573338a2fc):
Next up:
_
there... but it's not for general use. I don't know if some fancy ideas like we do with Attributes in Swift Tracing and keypaths like SwiftUI does can help here but I'll investigate.
All things applied...
I also looked at @adam-fowler's adoption inside Soco and other projects and am confident we've arrived at something very good.
We're aiming to settle down the discussions this week and being the new repos shortly. Thank you everyone for your patience and reviews, hopefully we're "done" here soon.
I'm waiting for some feedback from the SPM team about the package structure, once I get that I think we're ready to go here. Planning to land this end of this week.
Okey folks, so it seems we'll need two repositories.
The exact package and module naming we have to run through some reviews... Until then I'd like to merge this so we're out of the limbo on the types themselves :-)
This is a large PR, but in it I hope to finalize the API of this package.
It first and foremost acknowledges issues that we all felt already with the Carrier design -- it's too "wide open" and by being such, it actually hurts composability of libraries.
Short discussion:
In general we need to balance a number of needs here:
Logger
aroundAs such I propose the following simplification of the APIs:
Modules & Types
The package:
swift-context
The baggage module:
import Baggage
Baggage
- the "carrier" of baggage items; it is used by instrumentation and tracing to instrument systemsThe only user of this I really see being NIO, the team said it would not want to depend on
SwiftLog
.And finally, tieing logging and context together in:
import BaggageContext
SwiftLog
Context
Context
is EXACTLYLogger + Baggage
, nothing more, nothing lessWe also offer:
BaggageProtocol
in moduleBaggage
.traceID
be accessible DIRECTLY on it's contextand
ContextProtocol
in moduleBaggageContext
.baggage
but does NOT enforce allowing to mutate itThere are NO other types. The
EventLoop
we really tried hard to find a place for but we quickly devolve into complexities of various libraries wanting to accept or not wanting to accept it etc. The "...Carriers" design falls flat #28 on delivering good compositionality, in general remaining true to the:In this proposal we choose MORE constraints what a context and baggage is, and thus end up with a more composable API.
The short version is:
ContextProtocol
ContextProtocol
Optional:
BaggageProtocol
exists to allow certain types (framework contexts) get the.traceID
properties via extensions defined in other librariesBaggageProtocol
MUST NOT be required when accepting a context valueAnd finally:
Baggage
struct, if they require no logging.Baggage
MAY be stored ONLY in especial cases, such as NIO offering it on it's Context in order to pass it between handlersBaggageProtocol
as these are separate concerns -- "passing around things" (the baggage struct) vs. "be a nice DSLy type where keys get autocompleted" (the protocol conformance)As framework author e.g. "http server" or similar, where a widely used context object exists that holds many many values already (e.g. Vapor, Lambda Runtime)
MyFrameworkContext
toContextProtocol
and ensure thelogger
is implemented correctly (documentation on the property explains how)MyFrameworkContext
toBaggageProtocol
Baggage
itself.extension BaggageProtocol { var traceID: ... {} }
thistraceID
will be accessible on YOUR framework context directly:myFrameworkContext.traceID
rather thanmyFrameworkContext.baggage.traceID
ContextProtocol
-- i.e. be "wide" in set of accepted contexts when possibleAs library author of a library which does not have it's own "context" and/or is mostly a client e.g. HTTPClient:
ContextProtocol
in your API functionsAs library/framework user
"keep passing along the context you were given"
If unable to get a context, prefer using the
.TODO("Not sure where to get a context from?")
rather than the.background
factory for the contextDefine any additional baggage keys using
private enum MyKey: Baggage.Key { ... }
and theextension BaggageContext { var my: MyKey.Value { ... }
pattern.The code is mostly "shuffling around" and naming, and making sure everything "fits".
The general "what is possible to express" remains the same and wider -- I made sure this will fit existing context types such as Vapor, soco (AWSSDK), NIO, HTTPClient, Redis. Yes, it does mean passing the event loop explicitly and I really can't find a truely good way to solve it. We end up in arbitrarily tying things together which should not be together if we try to do so.
Please have a look everyone: @adam-fowler @tomerd @lukasa @slashmo @fabianfett @tanner0101 @pokryfka