1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//! Synchronization/thread-safety wrapper components (#146).
//!
//! These wrappers do not implement or redesign the M10 multi-threaded local
//! execution model; today's chunk runtime drives one component call at a
//! time. They also do not relax or grant any `Send`/`Sync` bound: a delegate
//! `P: ItemProcessor<I, O>` or `W: ItemWriter<O>` already requires
//! `Send + Sync` by [`crate::ItemProcessor`]/[`crate::ItemWriter`]'s own
//! supertraits, with or without this wrapper. What these wrappers establish
//! is a
//! *behavioral*, not a type-level, guarantee ADR-0008's composition rules
//! permit a wrapper to add on top of its delegate: a real mutual-exclusion
//! boundary around the delegate's call, enforced by an async-aware lock held
//! for the delegate's entire call (including any `.await` inside it), so a
//! delegate that is `Sync` at the type level (as the trait already demands)
//! but whose internal protocol or resource is only correct under strictly
//! serialized access can be shared safely by callers that might otherwise
//! invoke it concurrently (an application-owned executor, or a future M10
//! caller). This is the one case Gate E allows a wrapper to *strengthen*
//! rather than only meet: the wrapper's own synchronization is a capability
//! it genuinely provides itself, not one falsely inferred from the delegate.
use Mutex;
use crate::;
/// Serializes calls to a delegate [`crate::ItemProcessor`] behind an
/// async-aware mutex.
///
/// # Contract
///
/// - **Input/output**: `I -> O`, same as the delegate `P`.
/// - **State/checkpoint**: none added; opaque pass-through to `P`.
/// - **Ordering**: does not itself reorder; under contention, calls complete
/// in the order they acquire the lock (first-acquired, first-served for a
/// `tokio::sync::Mutex`, not a hard FIFO guarantee).
/// - **Thread safety**: `Send + Sync` exactly when `P` is -- `P` already
/// requires `Send + Sync` as an [`crate::ItemProcessor`], so this wrapper
/// grants no new type-level bound. What it genuinely adds is a *runtime*
/// guarantee no `ItemProcessor` bound alone gives a caller: at most one
/// call to `P` is ever in flight, even under concurrent shared
/// invocation, for the delegate's entire call including any internal
/// `.await`. See
/// `synchronized_processor_allows_at_most_one_delegate_call_in_flight` in
/// the evidence file below, which measures actual concurrent in-flight
/// delegate calls rather than only observing each call's individual
/// result.
/// - **Reentrancy**: not reentrant; a delegate that calls back into the same
/// wrapper instance while already holding the lock deadlocks. This mirrors
/// the lock it uses and is not a framework-level limitation.
/// - **Transaction/delivery**: not applicable.
/// - **Bounded resource**: no queueing beyond the lock's own FIFO-ish
/// waiters; this wrapper adds no buffering.
/// - **Cancellation**: honors the call-scoped stop token exactly as `P`
/// would; a stop request does not cancel a wait already queued on the
/// lock.
/// - **Close**: nothing to close.
/// - **Malformed input**: propagates the delegate's [`ProcessorError`]
/// unchanged.
/// - **Support tier**: first-party.
/// - **Evidence**: `crates/oxide-batch-test/tests/item_components_decorators.rs`.
/// Serializes calls to a delegate [`crate::ItemWriter`] behind an
/// async-aware mutex.
///
/// # Contract
///
/// Identical to [`SynchronizedProcessor`], for the writer role: exactly one
/// call to the delegate `W` is in flight at a time, for its entire call
/// including any internal `.await`, including whatever portion of the
/// enlisted transaction call that entails.
///
/// - **Evidence**: `crates/oxide-batch-test/tests/item_components_decorators.rs`.