Skip to content

Commit 8a0df74

Browse files
authored
feat(metadata): introduce mux_state_machine with state impls (#2544)
Implement `users` , `streams`, `consumer_groups` states for MuxStateMachine.
1 parent e58bee3 commit 8a0df74

44 files changed

Lines changed: 2334 additions & 91 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.lock

Lines changed: 5 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/common/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ fast_async_lock = ["dep:fast-async-mutex"]
3636
aes-gcm = { workspace = true }
3737
ahash = { workspace = true }
3838
base64 = { workspace = true }
39+
blake3 = { workspace = true }
3940
bon = { workspace = true }
4041
byte-unit = { workspace = true }
4142
bytemuck = { workspace = true }
@@ -57,6 +58,7 @@ humantime = { workspace = true }
5758
nix = { workspace = true }
5859
once_cell = { workspace = true }
5960
rcgen = "0.14.6"
61+
ring = "0.17.14"
6062
rustls = { workspace = true }
6163
serde = { workspace = true }
6264
serde_json = { workspace = true }

core/common/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ pub use types::message::*;
8888
pub use types::partition::*;
8989
pub use types::permissions::permissions_global::*;
9090
pub use types::permissions::personal_access_token::*;
91+
pub use types::personal_access_tokens::*;
9192
pub use types::snapshot::*;
9293
pub use types::stats::*;
9394
pub use types::stream::*;
@@ -100,6 +101,7 @@ pub use utils::checksum::*;
100101
pub use utils::crypto::*;
101102
pub use utils::duration::{IggyDuration, SEC_IN_MICRO};
102103
pub use utils::expiry::IggyExpiry;
104+
pub use utils::hash::*;
103105
pub use utils::personal_access_token_expiry::PersonalAccessTokenExpiry;
104106
pub use utils::text;
105107
pub use utils::timestamp::*;

core/common/src/types/consensus/message.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -89,24 +89,25 @@ where
8989
}
9090
}
9191

92-
/// Replace the header with a new one, using the provided function to generate it.
93-
pub fn replace_header<T: ConsensusHeader>(self, f: impl FnOnce(&H) -> T) -> Message<T> {
92+
/// Transmute the header to a different type, using the provided function to modify the new header.
93+
pub fn transmute_header<T: ConsensusHeader>(self, f: impl FnOnce(H, &mut T)) -> Message<T> {
9494
assert_eq!(size_of::<H>(), size_of::<T>());
95-
let prev = self.header();
96-
let header = f(prev);
9795

98-
let header_bytes = bytemuck::bytes_of(&header);
99-
let buffer = self.into_inner();
96+
// Copy old header to stack to avoid UB.
97+
let old_header = *self.header();
98+
10099
// Safety: We ensured that size_of::<H>() == size_of::<T>()
101100
// On top of that, there is going to be only one reference to buffer during this function call
102101
// so no other references can observe the mutation.
103102
// In the future we can replace the `Bytes` buffer with something that does not allow sharing between different threads.
103+
let buffer = self.into_inner();
104104
unsafe {
105105
let ptr = buffer.as_ptr() as *mut u8;
106-
let slice = std::slice::from_raw_parts_mut(ptr, buffer.len());
107-
slice[..size_of::<H>()].copy_from_slice(header_bytes);
106+
let slice = std::slice::from_raw_parts_mut(ptr, size_of::<T>());
107+
let new_header = bytemuck::from_bytes_mut(slice);
108+
f(old_header, new_header);
108109
}
109-
// TODO: Recalculate checksums
110+
110111
Message {
111112
buffer,
112113
_marker: PhantomData,

core/common/src/types/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub(crate) mod identifier;
2929
pub(crate) mod message;
3030
pub(crate) mod partition;
3131
pub(crate) mod permissions;
32+
pub(crate) mod personal_access_tokens;
3233
pub(crate) mod snapshot;
3334
pub(crate) mod stats;
3435
pub(crate) mod stream;

core/server/src/streaming/personal_access_tokens/personal_access_token.rs renamed to core/common/src/types/personal_access_tokens/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@
1515
* specific language governing permissions and limitations
1616
* under the License.
1717
*/
18-
use crate::streaming::utils::hash;
19-
use iggy_common::IggyExpiry;
20-
use iggy_common::IggyTimestamp;
21-
use iggy_common::UserId;
22-
use iggy_common::text::as_base64;
18+
use crate::IggyExpiry;
19+
use crate::IggyTimestamp;
20+
use crate::UserId;
21+
use crate::text::as_base64;
22+
use crate::utils::hash;
2323
use ring::rand::SecureRandom;
2424
use std::sync::Arc;
2525

@@ -96,8 +96,8 @@ impl PersonalAccessToken {
9696
#[cfg(test)]
9797
mod tests {
9898
use super::*;
99-
use iggy_common::IggyDuration;
100-
use iggy_common::IggyTimestamp;
99+
use crate::IggyDuration;
100+
use crate::IggyTimestamp;
101101

102102
#[test]
103103
fn personal_access_token_should_be_created_with_random_secure_value_and_hashed_successfully() {

core/common/src/utils/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub(crate) mod checksum;
2020
pub(crate) mod crypto;
2121
pub(crate) mod duration;
2222
pub(crate) mod expiry;
23+
pub(crate) mod hash;
2324
pub(crate) mod personal_access_token_expiry;
2425
pub mod text;
2526
pub(crate) mod timestamp;

core/consensus/src/impls.rs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -513,22 +513,22 @@ impl Project<Message<PrepareHeader>> for Message<RequestHeader> {
513513
fn project(self, consensus: &Self::Consensus) -> Message<PrepareHeader> {
514514
let op = consensus.sequencer.current_sequence() + 1;
515515

516-
self.replace_header(|prev| {
517-
PrepareHeader {
516+
self.transmute_header(|old, new| {
517+
*new = PrepareHeader {
518518
cluster: consensus.cluster,
519-
size: prev.size,
519+
size: old.size,
520520
epoch: 0,
521521
view: consensus.view.get(),
522-
release: prev.release,
522+
release: old.release,
523523
command: Command2::Prepare,
524524
replica: consensus.replica,
525525
parent: 0, // TODO: Get parent checksum from the previous entry in the journal (figure out how to pass that ctx here)
526-
request_checksum: prev.request_checksum,
527-
request: prev.request,
526+
request_checksum: old.request_checksum,
527+
request: old.request,
528528
commit: consensus.commit.get(),
529529
op,
530530
timestamp: 0, // 0 for now. Implement correct way to get timestamp later
531-
operation: prev.operation,
531+
operation: old.operation,
532532
..Default::default()
533533
}
534534
})
@@ -537,25 +537,26 @@ impl Project<Message<PrepareHeader>> for Message<RequestHeader> {
537537

538538
impl Project<Message<PrepareOkHeader>> for Message<PrepareHeader> {
539539
type Consensus = VsrConsensus;
540+
540541
fn project(self, consensus: &Self::Consensus) -> Message<PrepareOkHeader> {
541-
self.replace_header(|prev| {
542-
PrepareOkHeader {
542+
self.transmute_header(|old, new| {
543+
*new = PrepareOkHeader {
543544
command: Command2::PrepareOk,
544-
parent: prev.parent,
545-
prepare_checksum: prev.checksum,
546-
request: prev.request,
545+
parent: old.parent,
546+
prepare_checksum: old.checksum,
547+
request: old.request,
547548
cluster: consensus.cluster,
548549
replica: consensus.replica,
549550
epoch: 0, // TODO: consensus.epoch
550551
// It's important to use the view of the replica, not the received prepare!
551552
view: consensus.view.get(),
552-
op: prev.op,
553+
op: old.op,
553554
commit: consensus.commit.get(),
554-
timestamp: prev.timestamp,
555-
operation: prev.operation,
555+
timestamp: old.timestamp,
556+
operation: old.operation,
556557
// PrepareOks are only header no body
557558
..Default::default()
558-
}
559+
};
559560
})
560561
}
561562
}

core/metadata/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,11 @@ repository = "https://github.com/apache/iggy"
2828
readme = "../../../README.md"
2929

3030
[dependencies]
31+
ahash = { workspace = true }
32+
bytes = { workspace = true }
3133
consensus = { path = "../consensus" }
3234
iggy_common = { path = "../common" }
3335
journal = { path = "../journal" }
3436
message_bus = { path = "../message_bus" }
37+
slab = "0.4.11"
3538
tracing = { workspace = true }

0 commit comments

Comments
 (0)