myfs-hub: in-memory MapDB fallback (no sqlite_path) silently discards all uploaded blocks and reports false block_exists #39
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
When the server config has no
sqlite_path,myfs-hubfalls back todb::DBType::MapDB.MapDBis a stub: it stores nothing and returns placeholder values. The server still answers201 CreatedtoPOST /api/v1/blockandPOST /api/v1/file, so operators get a server that accepts uploads and silently throws the data away — with no error anywhere.Evidence
myfs-hub/src/server/mod.rs:myfs-hub/src/server/db/map.rs:Why this is bad
store_block→Ok(true): upload "succeeds", data gone.block_exists→true: clients that check-before-upload (e.g.myfs upload/verify_blocks_handler) conclude the block is already on the server and skip it — so even a later switch to a real DB won't have the data.get_block/get_file_by_hash→None: every download 404s, with no hint that the server was misconfigured.config.rsdoes not requiresqlite_path, so this is the default for any config that omits it.Suggested fix
Either:
MapDBfallback and makesqlite_pathmandatory inparse_config(fail fast with a clear config error); orMapDBa real in-memory store (back the block/file maps withHashMaps, implementstore_block/get_block/block_exists/etc.) so it behaves correctly for tests and ephemeral use.Option (1) is safest for production; (2) is nicer for tests. Whatever the choice,
store_blockmust not returnOk(true)while doing nothing.Spec: Implement MapDB as a real in-memory store
Problem
MapDBinmyfs-hub/src/server/db/map.rsis a stub: every method either returns ahardcoded placeholder or does nothing. This means a server configured without
sqlite_pathsilently discards uploaded blocks and pretends they exist(
block_existsreturnstrue).Solution
Replace the stub implementations with real
HashMap-backed storage. The MapDBstruct gains three maps and a download counter. Thread safety is provided by
std::sync::Mutex— MapDB is already behindArc<DBType>at the call site andall methods are
&self, so interior mutability is required.MapDB struct (changed)
Mutex<HashMap<...>>for each mutable collection — fine granularity avoids asingle big lock.
usersstays immutable after construction (no user registration at runtime).Method implementations
block_existsblock_metafor the givenblock_hash. Returntrueif present AND matchesfile_hash,block_index,user_id.store_blockblocks(key = block_hash, value = data). Insert intoblock_meta. ReturnOk(true)on first insert,Ok(false)if already present.get_blockhashinblocks. ReturnOk(Some(data))orOk(None).get_file_by_hashhashinfiles. ReturnOk(Some(file))orOk(None).get_file_blocks_orderedblock_metafiltered byfile_hash, collect(block_hash, block_index)sorted by index.list_blocksblockskeys, apply pagination (page/per_page).get_user_blocksblock_metafiltered byuser_id, apply pagination.increment_block_downloadsdownloads[hash]: increment count, add data size.get_block_downloadsdownloads.get(hash).cloned().unwrap_or((0, 0)).Pagination helper
A private helper:
Clips
pageandper_pageto sensible bounds (page >= 1, per_page 1..100),slices the sorted list, and returns the total count.
Files changed
Only one file:
myfs-hub/src/server/db/map.rs.No changes to
config.rs,mod.rs,server/mod.rs, or any other file — theMapDB constructor signature stays the same, and
DBType::MapDBdispatchesthrough the existing trait impl.
Risk
None beyond the scope of MapDB itself — SqlDB and the rest of the codebase are
untouched. No change to the config schema or public API.