Skip to content

Conversation

@muhamadazmy
Copy link
Contributor

@muhamadazmy muhamadazmy commented Oct 2, 2025

[storage] Envelope v2

Summary

  • Separate header, keys, and other envelope related
    information from the actual payload of the envelope
  • Ability to decode envelope header without decoding the full envelope
  • Support different encoding for the payload (records) (flexbuffers, or bilrost)
  • Delay decoding of payload until needed

TODO:

  • Decode v1 envelope into v2
  • Use Envelope v2 in code
  • Convert from v2 to v1 (to write)

Stack created with Sapling. Best reviewed with ReviewStack.

@muhamadazmy
Copy link
Contributor Author

@tillrohrmann in case you want to take a look the interesting parts are in the v2.rs file in this PR

}

#[derive(Debug, Clone, Copy, bilrost::Message)]
pub struct MessageIndexRecrod {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: Record.

pub index: MessageIndex,
}

bilrost_storage_encode_decode!(MessageIndexRecrod);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps the type should be named after the wal command (i.e. TruncateOutboxRequest) which btw needs to contain the PartitionId.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree! As for the partition-id this record message was mapped 1:1 from v1 without much thought about the payload it carries. I think the reason it doesn't have the partition id is that that's part of the envelope Header (destination)

#[bilrost(3)]
dedup: Dedup,
#[bilrost(4)]
keys: Keys,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this is actually needed. On the read path, we ship the keys directly from bifrost (one layer up from the envelope). On the write-path, the appender needs the input record to implement HasRecordKeys which could be implemented on a wrapper type used as input to the appender. Essentially making the input type different than output type to save a few bytes on each record.

impl WithPartitionKey for Header {
fn partition_key(&self) -> PartitionKey {
match self.destination {
Destination::None => unimplemented!("expect destinationt to be set"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo @ destinationt

#[bilrost(1)]
source: Source,
#[bilrost(2)]
destination: Destination,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

destination is potentially unnecessary unless you see a clear use-case for it.

{
match kind {
StorageCodecKind::FlexbuffersSerde => {
todo!("implement loading from envelop V1")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
todo!("implement loading from envelop V1")
todo!("implement loading from envelope V1")

record! {
@name=PurgeJournal,
@kind=RecordKind::PurgeJournal,
@payload=PurgeInvocationRequest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it true that it has the exact same payload as PurgeInvocation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what v1 does. Yes.

@muhamadazmy muhamadazmy force-pushed the pr3853 branch 3 times, most recently from 60e7920 to 2b53068 Compare October 14, 2025 10:26
@muhamadazmy muhamadazmy force-pushed the pr3853 branch 6 times, most recently from 505bbf7 to 8e7cd15 Compare November 19, 2025 13:12
@muhamadazmy muhamadazmy marked this pull request as ready for review November 19, 2025 13:14
@muhamadazmy muhamadazmy changed the title [storage] Draft for Envelope v2 [storage] Envelope v2 Nov 19, 2025
@muhamadazmy muhamadazmy force-pushed the pr3853 branch 2 times, most recently from c7dba21 to fc48bd2 Compare November 21, 2025 11:19
@muhamadazmy muhamadazmy marked this pull request as draft November 21, 2025 12:01
@muhamadazmy muhamadazmy force-pushed the pr3853 branch 2 times, most recently from 93592e3 to a5eea7e Compare November 21, 2025 16:11
# Summary
- Separate header, keys, and other envelope related
information from the actual payload of the envelope
- Ability to decode envelope header without decoding the full envelope
- Support different encoding for the payload (records) (flexbuffers, or bilrost)
- Delay decoding of payload until needed

# TODO:
- [x] Decode v1 envelope into v2
- [ ] Use Envelope v2 in code
- [ ] Convert from v2 to v1 (to write)
@muhamadazmy muhamadazmy marked this pull request as ready for review November 24, 2025 11:16
/// and serialization details required to interpret the payload.
#[derive(Debug, Clone, bilrost::Message)]
pub struct Header {
#[bilrost(1)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any particular reason why those tags are not 1,2,3?

where
Self: Sized,
{
debug_assert_eq!(kind, $crate::storage::StorageCodecKind::Bilrost);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'd suggest we make this an assert_eq

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants