Persistence API Reference¶
Brokerless producer-crash durability: persist durable pub/sub streams to an
object store (S3/MinIO or in-memory) and serve their history back — no zenohd
router and no native Zenoh storage plugin. See the
Brokerless Durable Messaging
guide.
Brokerless durable pub/sub persistence — Path B (in-process, no plugin, no router).
Zenoh's own durability (AdvancedPublisher in :mod:istos.communication.durable)
keeps a bounded replay cache in the producer's RAM: great across subscriber
disconnects, but it dies with the producer and holds only the last N samples.
This module closes that gap without a broker or a native Zenoh storage plugin
(which can only run inside a zenohd router). Instead Istos plays the storage
role itself, in Python:
- a writer subscribes to the key expression and persists every sample to an object store (S3/MinIO, or in-memory for tests), and
- a history queryable answers
session.get(key)by replaying stored samples back — so a late-joining or recovering subscriber can fetch history even after the original producer has crashed, as long as some Istos process hosts the role (co-located with the publisher, or a standalone persistence node runningapp.persist(key, "s3://…")).
Object keys are minted per sample (<key>/<millis>-<seq>), so the store keeps
the whole stream rather than a last-value-wins snapshot — the log semantics a
key-value backend does not give you for free.
InMemoryObjectStore
¶
Bases: ObjectStore
In-process store — the zero-dependency default and the test double.
Durable only for the lifetime of the process, so it does not add
producer-crash safety; it exists so persistence can be exercised (and unit
tested) without S3, and as a sane fallback for memory:// URLs.
Source code in src/istos/communication/persist.py
ObjectStore
¶
Bases: ABC
A minimal append-and-list object store for persisted samples.
Implementations must be safe to call from an asyncio event loop. Keys are
opaque strings that sort lexicographically in publish order (the role mints
them as <sample-key>/<millis>-<seq>).
Source code in src/istos/communication/persist.py
close()
async
¶
history(prefix, since=None)
abstractmethod
async
¶
Return (key, payload) for stored objects under prefix,
oldest-first. With since (a key returned by an earlier call), return
only objects that sort strictly after it — resumable replay.
Source code in src/istos/communication/persist.py
put(key, payload)
abstractmethod
async
¶
PersistRole
¶
Binds a Zenoh key expression to an :class:ObjectStore.
Declares two things on the shared session:
- a writer subscriber that persists every incoming sample, and
- a history queryable that replays persisted samples to any
session.get(key)— this is what serves history after a producer dies.
The store is serializer-agnostic: it persists and replays the raw sample payload bytes exactly as they went on the wire.
Source code in src/istos/communication/persist.py
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 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 | |
ReplayEvent
dataclass
¶
One event read back from the durable log.
position is an opaque cursor — persist it and pass it as since= to
resume after it. timestamp_ms is when the event was persisted.
Source code in src/istos/communication/persist.py
S3ObjectStore
¶
Bases: ObjectStore
S3/MinIO-backed store using aioboto3 (the istos[s3] extra).
Credentials come from the standard AWS chain — environment variables
(AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN),
~/.aws/credentials, or an instance/IAM role in production. Secrets are
never taken from the URL. Pass them explicitly only for local/dev (e.g.
MinIO) via access_key_id / secret_access_key.
Endpoint / region (needed for MinIO or a non-default region) may be given as constructor kwargs or in the URL query string, e.g.::
s3://my-bucket/streams?endpoint=http://localhost:9000®ion=us-east-1
Every persisted sample becomes one immutable object, so the bucket accumulates the full stream and survives producer restarts — the durability the in-RAM replay cache lacks.
Source code in src/istos/communication/persist.py
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | |
from_url(url, **kwargs)
classmethod
¶
Build from s3://bucket/prefix?endpoint=…®ion=….
Query params endpoint/endpoint_url and region/region_name
configure a custom endpoint (MinIO) and region. Explicit kwargs win
over query params. Credentials are intentionally not parsed from the URL.
Source code in src/istos/communication/persist.py
parse_store_url(url)
¶
Build an :class:ObjectStore from a URL.
s3://bucket/prefix(also MinIO viaendpoint_url) → :class:S3ObjectStorememory://anything→ :class:InMemoryObjectStore