Awesome, thanks so much!
On Tue, Feb 14, 2023, 8:01 PM Kenton Varda <[email protected]> wrote:
> Hi Matt,
>
> Your idea would work initially, but if an @3 field were ever added, it
> could end up incompatible.
>
> Instead, assuming `Internal` is a struct type, you can instead declare
> `internal` to have type `AnyPointer`:
>
> struct Event {
> union {
> foo @0 : Foo;
> bar @1 : Bar;
> internal @2: AnyPointer;
> }
> }
>
> Since `Internal` is a struct, a field of type `Internal` is represented as
> a pointer. Since `AnyPointer` is also a pointer, it'll produce the same
> layout.
>
> At the risk of over-engineering, another option would be to use generics:
>
> struct Event(InternalType) {
> union {
> foo @0 : Foo;
> bar @1 : Bar;
> internal @2: InternalType;
> }
> }
>
> This way, you and your consumers can actually use exactly the same
> definition of `Event`. Your consumers would use `Event<>` (which is
> equivalent to `Event<capnp::AnyPointer>`). In your internal code with
> knowledge of the internal type, you'd use `Event<Internal>`.
>
> -Kenton
>
> On Tue, Feb 14, 2023 at 1:21 PM Matt Stern <[email protected]> wrote:
>
>> Hi Capnp folks,
>>
>> I have a producer that writes events to a queue. The schema looks like:
>>
>> struct Event {
>> union {
>> foo @0 : Foo;
>> bar @1 : Bar;
>> internal @2 : Internal;
>> }
>> }
>>
>> There are downstream consumers of this queue that are meant to ignore the
>> "internal" field -- in fact, we don't even provide the Internal struct
>> definition to them.
>>
>> The downstream consumers have had a lot of log spam lately because they
>> use this stripped down schema to generate code:
>>
>> struct Event {
>> union {
>> foo @0 : Foo;
>> bar @1 : Bar;
>> }
>> }
>>
>> and then handle the union with a switch/case like so:
>>
>> switch (reader.which()) {
>> case FOO: return handle(reader.getFoo());
>> case BAR: return handle(reader.getBar());
>> default: return logError("A new message type exists that we don't know
>> about!");
>> }
>>
>> The default case in the switch makes sense -- if a new message type
>> appears from the producer, we should surface that in some way so the
>> consumers know to update their schemas and handle the new message. However,
>> we don't want to trigger this case for the known Internal type, which
>> consumers don't need to handle.
>>
>> I am thinking of giving the consumers a new schema that looks like:
>>
>> struct Event {
>> union {
>> foo @0 : Foo;
>> bar @1 : Bar;
>> internal @2: Void;
>> }
>> }
>>
>> so they can explicitly ignore the internal messages but still log errors
>> for other new messages that may appear.
>>
>> My question boils down to: Is it safe for the producer to assign one type
>> (struct Internal) to field 2 but the consumer to assign another type
>> (Void)? Or would this cause issues?
>>
>> Thanks!
>>
>> --
>> 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/f94fe404-b080-4654-bfc6-c578c411cf55n%40googlegroups.com
>> <https://groups.google.com/d/msgid/capnproto/f94fe404-b080-4654-bfc6-c578c411cf55n%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>
--
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/CAL717_Rt-%2BRygcn_ewFCLaqhLYQ3MVuVsXbRP1M7jZmsHOkwJw%40mail.gmail.com.