Server Distributed Tracing

Both Application and Request have Storage as a stored property. This allows for the developer and third party packages to easily extend these types. This works particularly well with Swift's extensions, for example:

extension Request {
    private struct Foo: StorageKey {
        typealias Value = Bool
    }
    
    var foo: Bool? {
        get { self.storage[Foo.self] }
        set { self.storage[Foo.self] = newValue }
    }
}

It functions similarly to the userInfo: [AnyHashable: Any] pattern many Apple libraries use.

Ah, ok I see. That makes sense.

Most of these conversations have been IRL. (I found an SSWG meeting note about it here but that's not super helpful).

Static context access might look something like this:

func foo() {
    BaggageContext.current[SomeKey.self] = someValue
}

Doing this without static context access would look like:

func foo(baggage: inout BaggageContext) {
    baggage[SomeKey.self] = someValue
}

The key benefit to static access being that you don't need to "clutter" your API with context passing. Achieving static context passing in a one-thread-per-request based framework is fairly straightforward since you can use thread storage. Doing it in an event loop design like NIO is more complex. I'm not a Node.js expert, but it seems they allow static context passing in an event loop system with something called Continuation-Local-Storage. Whether or not doing this is a good idea, I don't know (http://asim-malik.com/the-perils-of-node-continuation-local-storage/).

FWIW, I'm not personally very invested in this type of context passing. Vapor opts for making it easier to pass things explicitly instead. I'm just interested if you planned on addressing it as a part of this proposal or had any thoughts.

Thanks!

1 Like