Repository navigation
Commit eeef85d
committed
feat(topic): add Topic.latest() for a single-read value + timestamp
Checking whether a published value is stale today means two calls:
long stamp = topic.latestPublishNanos();
T v = topic.latestValueOr(null);
long age = System.nanoTime() - stamp;
Both accessors are individually correct, but a publish can land between
them, leaving the caller holding a value from one publish and a timestamp
from another. Reading the timestamp first makes that safe in one
direction -- the age can only be over-reported, never under-reported --
but over-reporting still discards a fresh value as stale, by up to a full
publish interval.
How often that happens depends on how long the two reads take. Normally
they are nanoseconds apart and a publish landing between them is
vanishingly rare. It stops being rare when the reader is preempted
between the two calls by a GC pause or the scheduler, since the window
becomes milliseconds. This library configures a small young gen, so young
GCs are part of the deployment rather than a hypothetical.
`latest()` returns the value and its timestamp from one snapshot read, so
the pair provably comes from a single publish and the window does not
exist:
Optional<Topic.Latest<T>> snap = topic.latest();
T v = snap.map(Topic.Latest::value).orElse(default);
long age = snap.map(Topic.Latest::ageNanos).orElse(Long.MAX_VALUE);
Additive only. No existing signature or behaviour changes, and callers
that never check an age can keep using `latestValueOr` -- same single
volatile read.
`Topic.Latest` becomes public with `value()`, `publishNanos()` and
`ageNanos()`. `ageNanos()` is the age of *this* value computed from its
own stamp, which also removes the pre-publish `0` sentinel that the
two-call form has to guard against by hand.
`latestPublishNanos()` still returns 0 before the first publish, so the
guard stays necessary for anyone composing it by hand. It is documented as
such in the javadoc, the CHANGELOG and the topics guide.
The concurrency test's reader now uses `latest()`, which is the stronger
property: no straddle is representable, so the "timestamp first"
ordering rule has nothing left to guard. That test previously carried a
cross-check between `latest()` being empty and `latestPublishNanos()`
being nonzero; it is gone, because a publish can legitimately land
between those two reads and a nonzero stamp there says nothing about
consistency.
Suite: 61 tests, 0 failures.1 parent 54d881e commit eeef85d
5 files changed
Lines changed: 229 additions & 60 deletions
File tree
- src
- main/java/com/aaravlabs/synapse
- test/java/com/aaravlabs/synapse
- website/src/content/docs
- api
- concepts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
35 | 40 | | |
36 | 41 | | |
37 | 42 | | |
38 | 43 | | |
39 | 44 | | |
40 | 45 | | |
41 | 46 | | |
42 | | - | |
43 | | - | |
44 | | - | |
45 | | - | |
| 47 | + | |
| 48 | + | |
46 | 49 | | |
47 | 50 | | |
48 | | - | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
49 | 62 | | |
50 | | - | |
| 63 | + | |
51 | 64 | | |
52 | 65 | | |
53 | 66 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
53 | 61 | | |
54 | 62 | | |
55 | 63 | | |
56 | 64 | | |
57 | 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 | + | |
58 | 93 | | |
59 | 94 | | |
60 | 95 | | |
| |||
74 | 109 | | |
75 | 110 | | |
76 | 111 | | |
77 | | - | |
78 | | - | |
79 | | - | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
80 | 115 | | |
81 | 116 | | |
82 | 117 | | |
| |||
88 | 123 | | |
89 | 124 | | |
90 | 125 | | |
91 | | - | |
| 126 | + | |
92 | 127 | | |
93 | 128 | | |
94 | 129 | | |
| |||
110 | 145 | | |
111 | 146 | | |
112 | 147 | | |
113 | | - | |
| 148 | + | |
114 | 149 | | |
115 | 150 | | |
116 | 151 | | |
| |||
122 | 157 | | |
123 | 158 | | |
124 | 159 | | |
125 | | - | |
126 | | - | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
127 | 163 | | |
128 | 164 | | |
129 | 165 | | |
| |||
133 | 169 | | |
134 | 170 | | |
135 | 171 | | |
136 | | - | |
137 | | - | |
138 | | - | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
139 | 183 | | |
140 | 184 | | |
141 | 185 | | |
| |||
158 | 202 | | |
159 | 203 | | |
160 | 204 | | |
161 | | - | |
| 205 | + | |
| 206 | + | |
162 | 207 | | |
163 | 208 | | |
164 | 209 | | |
165 | 210 | | |
166 | 211 | | |
167 | 212 | | |
168 | | - | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
169 | 250 | | |
170 | 251 | | |
171 | 252 | | |
| |||
Lines changed: 81 additions & 22 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
78 | 78 | | |
79 | 79 | | |
80 | 80 | | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
81 | 84 | | |
82 | 85 | | |
83 | 86 | | |
| |||
106 | 109 | | |
107 | 110 | | |
108 | 111 | | |
109 | | - | |
110 | | - | |
111 | | - | |
112 | | - | |
113 | | - | |
114 | | - | |
115 | | - | |
116 | | - | |
117 | | - | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
118 | 126 | | |
119 | 127 | | |
120 | | - | |
121 | | - | |
122 | | - | |
123 | | - | |
124 | | - | |
125 | | - | |
126 | | - | |
127 | | - | |
128 | | - | |
129 | | - | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
130 | 131 | | |
131 | | - | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
132 | 142 | | |
133 | | - | |
134 | | - | |
| 143 | + | |
135 | 144 | | |
136 | 145 | | |
137 | 146 | | |
| |||
240 | 249 | | |
241 | 250 | | |
242 | 251 | | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
243 | 302 | | |
244 | 303 | | |
245 | 304 | | |
| |||
0 commit comments