Skip to content

Commit bac1da0

Browse files
authored
refactor!: restrict public items for misuse safety (#227)
1 parent d4a92c8 commit bac1da0

File tree

13 files changed

+461
-364
lines changed

13 files changed

+461
-364
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ reqwest = { version = "0.13.1", default-features = false, features = [
3737
"zstd",
3838
"rustls",
3939
] }
40-
s2-api = { git = "https://github.com/s2-streamstore/s2", rev = "b69e012f07290c9fb6ada77552362a93634287c7", package = "s2-api" }
41-
s2-common = { git = "https://github.com/s2-streamstore/s2", rev = "b69e012f07290c9fb6ada77552362a93634287c7", package = "s2-common" }
40+
s2-api = { git = "https://github.com/s2-streamstore/s2", rev = "6f50d0a1a133b8b4ee0fef900e586a0f10d75637", package = "s2-api" }
41+
s2-common = { git = "https://github.com/s2-streamstore/s2", rev = "6f50d0a1a133b8b4ee0fef900e586a0f10d75637", package = "s2-common" }
4242
secrecy = "0.10.3"
4343
serde = { version = "1.0.228" }
4444
serde_json = "1.0.148"
@@ -53,6 +53,9 @@ url = "2.5.7"
5353
urlencoding = "2.1.3"
5454
uuid = { version = "1.19.0", features = ["v4", "fast-rng"] }
5555

56+
[features]
57+
_hidden = []
58+
5659
[dev-dependencies]
5760
assert_matches = "1.5.0"
5861
rstest = "0.26.1"

examples/issue_access_token.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use s2::{
22
S2,
33
types::{
4-
AccessTokenScope, BasinMatcher, BasinName, IssueAccessTokenInput, Operation,
4+
AccessTokenScopeInput, BasinMatcher, BasinName, IssueAccessTokenInput, Operation,
55
OperationGroupPermissions, ReadWritePermissions, S2Config, StreamMatcher,
66
},
77
};
@@ -19,7 +19,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
1919

2020
let input = IssueAccessTokenInput::new(
2121
"ro-token".parse()?,
22-
AccessTokenScope::from_op_group_perms(
22+
AccessTokenScopeInput::from_op_group_perms(
2323
OperationGroupPermissions::new().with_account(ReadWritePermissions::read_only()),
2424
)
2525
.with_ops([Operation::CreateStream])

src/batching.rs

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,11 @@ use tokio::time::Instant;
1313
use crate::types::{AppendInput, AppendRecord, AppendRecordBatch, FencingToken, MeteredBytes};
1414

1515
#[derive(Debug, Clone)]
16-
#[non_exhaustive]
17-
/// Configuration for batching [AppendRecord]s.
16+
/// Configuration for batching [`AppendRecord`]s.
1817
pub struct BatchingConfig {
19-
/// How long to wait for more records before flushing a batch.
20-
///
21-
/// Defaults to `5ms`.
22-
pub linger: Duration,
23-
/// Maximum bytes per batch.
24-
///
25-
/// Defaults to `1MiB`.
26-
pub max_batch_bytes: usize,
27-
/// Maximum number of records per batch.
28-
///
29-
/// Defaults to `1000`.
30-
pub max_batch_records: usize,
18+
linger: Duration,
19+
max_batch_bytes: usize,
20+
max_batch_records: usize,
3121
}
3222

3323
impl Default for BatchingConfig {
@@ -41,21 +31,27 @@ impl Default for BatchingConfig {
4131
}
4232

4333
impl BatchingConfig {
44-
/// Create a new [BatchingConfig] with default settings.
34+
/// Create a new [`BatchingConfig`] with default settings.
4535
pub fn new() -> Self {
4636
Self::default()
4737
}
4838

49-
/// Set the linger duration.
39+
/// Set the duration for how long to wait for more records before flushing a batch.
40+
///
41+
/// Defaults to `5ms`.
5042
pub fn with_linger(self, linger: Duration) -> Self {
5143
Self { linger, ..self }
5244
}
5345

54-
/// Set the maximum bytes per batch.
46+
/// Set the maximum metered bytes per batch.
47+
///
48+
/// **Note:** It must not exceed `1MiB`.
49+
///
50+
/// Defaults to `1MiB`.
5551
pub fn with_max_batch_bytes(self, max_batch_bytes: usize) -> Result<Self, ValidationError> {
5652
if max_batch_bytes > RECORD_BATCH_MAX.bytes {
5753
return Err(ValidationError(format!(
58-
"max_batch_bytes: {max_batch_bytes} exceeds {}",
54+
"max_batch_bytes ({max_batch_bytes}) exceeds {}",
5955
RECORD_BATCH_MAX.bytes
6056
)));
6157
}
@@ -66,10 +62,14 @@ impl BatchingConfig {
6662
}
6763

6864
/// Set the maximum number of records per batch.
65+
///
66+
/// **Note:** It must not exceed `1000`.
67+
///
68+
/// Defaults to `1000`.
6969
pub fn with_max_batch_records(self, max_batch_records: usize) -> Result<Self, ValidationError> {
7070
if max_batch_records > RECORD_BATCH_MAX.count {
7171
return Err(ValidationError(format!(
72-
"max_batch_records: {max_batch_records} exceeds {}",
72+
"max_batch_records ({max_batch_records}) exceeds {}",
7373
RECORD_BATCH_MAX.count
7474
)));
7575
}
@@ -80,16 +80,15 @@ impl BatchingConfig {
8080
}
8181
}
8282

83-
#[non_exhaustive]
84-
/// A [Stream] that batches [AppendRecord]s into [AppendInput]s.
83+
/// A [`Stream`] that batches [`AppendRecord`]s into [`AppendInput`]s.
8584
pub struct AppendInputs {
8685
pub(crate) batches: AppendRecordBatches,
8786
pub(crate) fencing_token: Option<FencingToken>,
8887
pub(crate) match_seq_num: Option<u64>,
8988
}
9089

9190
impl AppendInputs {
92-
/// Create a new [AppendInputs] with the given records and config.
91+
/// Create a new [`AppendInputs`] with the given records and config.
9392
pub fn new(
9493
records: impl Stream<Item = impl Into<AppendRecord> + Send> + Send + Unpin + 'static,
9594
config: BatchingConfig,
@@ -101,15 +100,15 @@ impl AppendInputs {
101100
}
102101
}
103102

104-
/// Set the fencing token for all [AppendInput]s.
103+
/// Set the fencing token for all [`AppendInput`]s.
105104
pub fn with_fencing_token(self, fencing_token: FencingToken) -> Self {
106105
Self {
107106
fencing_token: Some(fencing_token),
108107
..self
109108
}
110109
}
111110

112-
/// Set the match sequence number for the initial [AppendInput]. It will be auto-incremented
111+
/// Set the match sequence number for the initial [`AppendInput`]. It will be auto-incremented
113112
/// for the subsequent ones.
114113
pub fn with_match_seq_num(self, seq_num: u64) -> Self {
115114
Self {
@@ -142,13 +141,13 @@ impl Stream for AppendInputs {
142141
}
143142
}
144143

145-
/// A [Stream] that batches [AppendRecord]s into [AppendRecordBatch]es.
144+
/// A [`Stream`] that batches [`AppendRecord`]s into [`AppendRecordBatch`]es.
146145
pub struct AppendRecordBatches {
147146
inner: Pin<Box<dyn Stream<Item = Result<AppendRecordBatch, ValidationError>> + Send>>,
148147
}
149148

150149
impl AppendRecordBatches {
151-
/// Create a new [AppendRecordBatches] with the given records and config.
150+
/// Create a new [`AppendRecordBatches`] with the given records and config.
152151
pub fn new(
153152
records: impl Stream<Item = impl Into<AppendRecord> + Send> + Send + Unpin + 'static,
154153
config: BatchingConfig,
@@ -203,7 +202,7 @@ fn append_record_batches(
203202
let record_bytes = first_record.metered_bytes();
204203
if record_bytes > config.max_batch_bytes {
205204
yield Err(ValidationError(format!(
206-
"record size ({record_bytes} bytes) exceeds max_batch_bytes ({})",
205+
"record size in metered bytes ({record_bytes}) exceeds max_batch_bytes ({})",
207206
config.max_batch_bytes
208207
)));
209208
break;
@@ -310,7 +309,7 @@ mod tests {
310309
}
311310

312311
#[tokio::test]
313-
async fn batching_should_fail_when_it_sees_oversized_record() -> Result<(), ValidationError> {
312+
async fn batching_should_error_when_it_sees_oversized_record() -> Result<(), ValidationError> {
314313
let record = AppendRecord::new("hello")?;
315314
let record_bytes = record.metered_bytes();
316315
let max_batch_bytes = 1;
@@ -324,7 +323,7 @@ mod tests {
324323
assert_matches!(&results[0], Err(err) => {
325324
assert_eq!(
326325
err.to_string(),
327-
format!("record size ({record_bytes} bytes) exceeds max_batch_bytes ({max_batch_bytes})")
326+
format!("record size in metered bytes ({record_bytes}) exceeds max_batch_bytes ({max_batch_bytes})")
328327
);
329328
});
330329

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ pub mod types;
9393
pub use ops::{S2, S2Basin, S2Stream};
9494
/// Append session for pipelining multiple appends with backpressure control.
9595
///
96-
/// See [AppendSession](append_session::AppendSession).
96+
/// See [`AppendSession`](append_session::AppendSession).
9797
pub mod append_session {
9898
pub use crate::session::append::{AppendSession, AppendSessionConfig, BatchSubmitTicket};
9999
}

src/ops.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ pub struct S2 {
2222
}
2323

2424
impl S2 {
25-
/// Create a new [S2].
25+
/// Create a new [`S2`].
2626
pub fn new(config: S2Config) -> Result<Self, S2Error> {
2727
Ok(Self {
2828
client: AccountClient::init(config)?,
2929
})
3030
}
3131

32-
/// Get an [S2Basin].
32+
/// Get an [`S2Basin`].
3333
pub fn basin(&self, name: BasinName) -> S2Basin {
3434
S2Basin {
3535
client: self.client.basin_client(name),
@@ -148,13 +148,13 @@ impl S2 {
148148
#[derive(Debug, Clone)]
149149
/// A basin in an S2 account.
150150
///
151-
/// See [S2::basin].
151+
/// See [`S2::basin`].
152152
pub struct S2Basin {
153153
client: BasinClient,
154154
}
155155

156156
impl S2Basin {
157-
/// Get an [S2Stream].
157+
/// Get an [`S2Stream`].
158158
pub fn stream(&self, name: StreamName) -> S2Stream {
159159
S2Stream {
160160
client: self.client.clone(),
@@ -215,7 +215,7 @@ impl S2Basin {
215215
#[derive(Debug, Clone)]
216216
/// A stream in an S2 basin.
217217
///
218-
/// See [S2Basin::stream].
218+
/// See [`S2Basin::stream`].
219219
pub struct S2Stream {
220220
client: BasinClient,
221221
name: StreamName,

src/producer.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use crate::{
2121
types::{AppendAck, AppendInput, AppendRecord, FencingToken, MeteredBytes, S2Error},
2222
};
2323

24-
/// A [Future] that resolves to an acknowledgement once the record is appended.
24+
/// A [`Future`] that resolves to an acknowledgement once the record is appended.
2525
pub struct RecordSubmitTicket {
2626
rx: oneshot::Receiver<Result<IndexedAppendAck, S2Error>>,
2727
}
@@ -40,6 +40,7 @@ impl Future for RecordSubmitTicket {
4040

4141
/// Acknowledgement for an appended record.
4242
#[derive(Debug, Clone)]
43+
#[non_exhaustive]
4344
pub struct IndexedAppendAck {
4445
/// Sequence number assigned to the record.
4546
pub seq_num: u64,
@@ -49,41 +50,41 @@ pub struct IndexedAppendAck {
4950

5051
#[derive(Debug, Clone, Default)]
5152
#[non_exhaustive]
52-
/// Configuration for [Producer].
53+
/// Configuration for [`Producer`].
5354
pub struct ProducerConfig {
54-
/// Configuration for batching records into [AppendInput]s before appending.
55+
/// Configuration for batching records into [`AppendInput`]s before appending.
5556
pub batching: BatchingConfig,
56-
/// Fencing token for all [AppendInput]s.
57+
/// Fencing token for all [`AppendInput`]s.
5758
///
5859
/// Defaults to `None`.
5960
pub fencing_token: Option<FencingToken>,
60-
/// Match sequence number for the initial [AppendInput]. It will be auto-incremented for the
61+
/// Match sequence number for the initial [`AppendInput`]. It will be auto-incremented for the
6162
/// subsequent ones.
6263
///
6364
/// Defaults to `None`.
6465
pub match_seq_num: Option<u64>,
6566
}
6667

6768
impl ProducerConfig {
68-
/// Create a new [ProducerConfig] with default settings.
69+
/// Create a new [`ProducerConfig`] with default settings.
6970
pub fn new() -> Self {
7071
Self::default()
7172
}
7273

73-
/// Set the configuration for batching records into [AppendInput]s before appending.
74+
/// Set the configuration for batching records into [`AppendInput`]s before appending.
7475
pub fn with_batching(self, batching: BatchingConfig) -> Self {
7576
Self { batching, ..self }
7677
}
7778

78-
/// Set the fencing token for all [AppendInput]s.
79+
/// Set the fencing token for all [`AppendInput`]s.
7980
pub fn with_fencing_token(self, fencing_token: FencingToken) -> Self {
8081
Self {
8182
fencing_token: Some(fencing_token),
8283
..self
8384
}
8485
}
8586

86-
/// Set the match sequence number for the initial [AppendInput]. It will be auto-incremented
87+
/// Set the match sequence number for the initial [`AppendInput`]. It will be auto-incremented
8788
/// for the subsequent ones.
8889
pub fn with_match_seq_num(self, match_seq_num: u64) -> Self {
8990
Self {
@@ -93,17 +94,17 @@ impl ProducerConfig {
9394
}
9495
}
9596

96-
/// High-level interface for submitting individual [AppendRecord]s.
97+
/// High-level interface for submitting individual [`AppendRecord`]s.
9798
///
98-
/// Wraps an [AppendSession] and handles batching records into [AppendInput]s automatically based on
99-
/// the provided [configuration](ProducerConfig).
99+
/// Wraps an [`AppendSession`] and handles batching records into [`AppendInput`]s automatically
100+
/// based on the provided [`configuration`](ProducerConfig).
100101
pub struct Producer {
101102
cmd_tx: mpsc::Sender<Command>,
102103
_handle: AbortOnDropHandle<()>,
103104
}
104105

105106
impl Producer {
106-
/// Create a new [Producer].
107+
/// Create a new [`Producer`].
107108
pub fn new(session: AppendSession, config: ProducerConfig) -> Self {
108109
let (cmd_tx, cmd_rx) = mpsc::channel::<Command>(RECORD_BATCH_MAX.count);
109110
let _handle = AbortOnDropHandle::new(tokio::spawn(Self::run(session, config, cmd_rx)));
@@ -112,8 +113,7 @@ impl Producer {
112113

113114
/// Submit a record for appending.
114115
///
115-
/// **Note**: You must call [Producer::close] if want to ensure all submitted records are
116-
/// appended.
116+
/// **Note**: You must call [`Producer::close`] to ensure all submitted records are appended.
117117
pub async fn submit(&self, record: AppendRecord) -> Result<RecordSubmitTicket, S2Error> {
118118
let (ack_tx, ack_rx) = oneshot::channel();
119119
self.cmd_tx

0 commit comments

Comments
 (0)