Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

class HomeBlocksConan(ConanFile):
name = "homeblocks"
version = "6.0.6"
version = "6.0.7"

homepage = "https://github.com/eBay/HomeBlocks"
description = "Block Store built on HomeStore"
Expand Down Expand Up @@ -108,7 +108,7 @@ def build(self):
cmake.configure()
cmake.build()
if not self.conf.get("tools.build:skip_test", default=False):
jobs = self.conf.get("tools.build:jobs", default=3)
jobs = self.conf.get("tools.build:jobs", default=4)
env = Environment()
env.define("CTEST_PARALLEL_LEVEL", str(jobs))
if self.options.get_safe("sanitize") == "thread":
Expand Down
14 changes: 9 additions & 5 deletions docs/craft/rpcs.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,15 @@ RAFT entry payload: { rs_commit_lsn: int64, client_token: uint64, empty_slots: [
Proposed by the leader via `CraftReplDev::append()` — triggered by login, the watchdog, the periodic
checkpoint, or the client-requested **Resolve** RPC (#5). **Before proposing**, the leader resolves
every unresolved slot ≤ `rs_commit_lsn`: fetch from any holder, or record an `Empty` verdict on
quorum-lacks evidence; it never proposes past an unresolved slot. On RAFT commit each replica: verify
the token, mark `empty_slots` as permanent no-op holes (discarding any local data there), fetch the
remaining missing slots from peers, then advance `commit_lsn`. Replicas never declare `Empty`
unilaterally. This is the primary recovery mechanism — it carries no write data, only the watermark
and verdicts.
quorum-lacks evidence; it never proposes past an unresolved slot. On RAFT commit each replica: mark
`empty_slots` as permanent no-op holes (discarding any local data there), fetch the remaining missing
slots from peers, then advance `commit_lsn` to the contiguous prefix bounded by `rs_commit_lsn` --
skipping `Empty` slots but never past an unresolved `Missing` one. `client_token` is carried on the
entry but not checked against local state at apply time: `SyncRSCommitLSN` applies before the
`InternalLogin` that would establish it, so an equality-fence here would make login itself unreachable;
ordering plus the term fence on subsequent IO provide exclusivity instead. Replicas never declare
`Empty` unilaterally. This is the primary recovery mechanism — it carries no write data, only the
watermark and verdicts.

---

Expand Down
4 changes: 2 additions & 2 deletions docs/craft/subtasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ and enforce single-writer exclusivity without data flowing through the RAFT log.
**SyncRSCommitLSN:**
- RAFT entry carries `{rs_commit_lsn, client_token, empty_slots[]}`
- **Leader pre-resolution:** before proposing `N`, the leader resolves every unresolved slot ≤ `N`: fetch it from any holder, or record an `Empty` verdict on quorum-lacks evidence (leader counts itself; non-responders never count); it must not propose past an unresolved slot
- On apply: verify token; mark `empty_slots` Empty, **discarding any local data held there** (reconciliation); if behind, `fetch_data()` the remaining missing slots from peers; then `commit_lsn = rs_commit_lsn`. **Apply never truncates** and replicas **never declare Empty unilaterally**
- Peer catch-up (`CraftPeerFetcher::fetch_from_peer`) is **timeout-bounded**: every call passes `peer_fetch_timeout_ms` (`home_blks_config.fbs`, default 5000ms); a peer that misses the deadline is treated as a hard failure, same as any other fetch failure (best-effort — `commit_lsn` still advances, unresolved LSNs stay missing). The interface only carries the deadline; enforcing it against a real wire call is S9's (the transport's)
- On apply: `client_token` is carried on the entry but NOT checked against local state -- `SyncRSCommitLSN` applies before the `InternalLogin` that would establish it, so an equality-fence here would make login itself unreachable; ordering plus the term fence on subsequent IO provide exclusivity instead. Mark `empty_slots` Empty, **discarding any local data held there** (reconciliation); if behind, `fetch_data()` the remaining missing slots from peers; then advance `commit_lsn` to the contiguous prefix bounded by `rs_commit_lsn` (skipping `Empty` slots, never past an unresolved `Missing` one). **Apply never truncates** and replicas **never declare Empty unilaterally**
- Peer catch-up (`CraftPeerFetcher::fetch_from_peer`) is **timeout-bounded**: every call passes `peer_fetch_timeout_ms` (`home_blks_config.fbs`, default 5000ms); a peer that misses the deadline is treated as a hard failure, same as any other fetch failure (best-effort — unresolved LSNs stay missing and `commit_lsn` stalls just below the first one). The interface only carries the deadline; enforcing it against a real wire call is S9's (the transport's)
- `append(sync_to, client_token)` proposes this entry via RAFT
- Triggers: periodic every N LSNs (configurable via `home_blks_config.fbs`, default 128), watchdog, login, **client-requested (after a failed sub-quorum write)** — the client's `Resolve` RPC lands on `CraftReplDev::request_resolution(term, upto)`, which runs this same leader pre-resolution and returns the Empty verdicts ≤ `upto` (`craft::resolution_result`). The client broadcasts it to every member (it cannot know the leader mid-session); a follower returns `NOT_LEADER`

Expand Down
2 changes: 1 addition & 1 deletion src/include/homeblks/home_blocks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ using volume_handle = std::shared_ptr< volume >;
// standard equivalent (invalid arg, no space, io error, unsupported op, ...) is returned as
// std::make_error_condition(std::errc::*) directly rather than duplicated here.
ENUM(volume_error, uint16_t, UNKNOWN_VOLUME = 1, CRC_MISMATCH, INDEX_ERROR, INTERNAL_ERROR, OFFLINE, STALE_TERM,
EMPTY_SLOT);
EMPTY_SLOT, WRONG_TOKEN, INVALID_ENTRY);

ENUM(volume_state, uint32_t,
INIT, // created, not yet online
Expand Down
Loading
Loading