Many protocols provide some way to attach metadata to requests & responses. 
HTTP and protocols derved from it provide this in the form of headers (and 
occasionally trailers), for example. 

There are various reasons why this can be very useful, even in a capability 
oriented system:
 * Propagating a request correlation ID from node to node as a call passes 
through multiple parts of a system for logging correlation purposes
 * Even better, propagating an OpenTracing SpanContext or similar to enable 
correlating multiple parts of an action in a distributed system with tools like 
Jaeger <https://www.jaegertracing.io/>
 * Attaching Lamport timestamps 
<https://en.wikipedia.org/wiki/Lamport_timestamp> to every request and reply, 
to propagate an inter-system causal ordering
These sorts of things are very useful to convey *implicitly*. When every node 
in your system deals in lamport timestamps, then manually annotating every call 
with a timestamp parameter & manually handling that parameter and adding it to 
the response will quickly get tedious. If you want to do distributed tracing, 
then you want that context everywhere.

These kinds of things represent the kind of state/context which is implicit 
from the callstack in traditional single-threaded applications

There are some other places where I think metadata could be useful, although 
they probably are also more matters of taste, like identity/authentication (one 
of my thoughts here is that sometimes it might be advantageous to use metadata 
to pass this kind of information because this ensures it is always in a uniform 
location where intermediate proxies/membranes can find it without needing to be 
aware of involved schemas. You could potentially see a system which implements 
authentication/authorisation through collaborating membranes where those 
membranes need to communicate identifying information with each other, for 
example.)

There are some questions that would need resolving:
 * How should metadata be represented? (I'd lean towards something like a 
Map<UInt64 TypeID, AnyPointer assumed to be of TypeID>)
 * What messages can it apply to? Call/Return are obvious, but there are other 
possibilities that might be necessary (Embargo/Disembargo? Provide/Accept? 
Join?). Maybe metadata should just be a paramete of the top-level message?
 * How to access/manipulate it? Presumably in C++ this could be exposed via 
CallContext on the server side / Request on the client side?
 * How to support "middleware" and/or pass such ambient context around? I feel 
the potentially "easy" option is for middleware to simply be a membrane, but 
ambient context will depend upon language. In Go you might use context.Context 
for example; not sure what you would do in e.g. KJ
I realise this probably opens several cans of worns, and that metadata tends to 
always be somewhat inelegant, but it seems worthwhile to talk about becuase 
it's important in lots of distributed systems scenarios.

- Erin


-- 
You received this message because you are subscribed to the Google Groups 
"Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/capnproto/9ccbf8e1-b013-4744-be5f-d7b789bfa555%40www.fastmail.com.

Reply via email to