Commit Graph
82 Commits
Author SHA1 Message Date
cozis 3da0eded42 First version of the HTTP proxy 2026-02-25 12:30:20 +01:00
cozis ef1d65ad2b Major refactoring 2026-02-25 10:44:43 +01:00
Claude 7da254fc45 Fix request_id mismatch causing 5s hang on every PUT commit
The COMMIT_PUT message was built with request_id N, then request_id
was incremented to N+1 immediately after sending. When the server
replied with request_id N, the client compared it against N+1,
silently discarded the reply, and waited for the 5-second timeout.
The timeout retry (replay_request) then resent with N+1, which
matched — so every PUT paid an unnecessary 5-second penalty.

Move the request_id++ before building the CommitPutMessage, matching
the pattern already used by toastyfs_async_delete.

https://claude.ai/code/session_01EG3WZSH3ZeTdAbb5T42r2w
2026-02-21 23:36:18 +00:00
Claude 15a2713116 Fix client hanging on first operation by queuing message during connect
When no TCP connection exists, send_message_to_server() called
tcp_connect() with a NULL output parameter and returned without
sending the message. The message was silently dropped, and the only
recovery was the 5-second PRIMARY_DEATH_TIMEOUT_SEC retry — causing
the client to hang on every cold-connection operation.

tcp_connect() already supports returning the output ByteQueue so
callers can queue data to be flushed once the connection completes.
Use that mechanism: get the output queue from tcp_connect() and
write the message into it immediately, so it is sent as soon as
the TCP handshake finishes.

https://claude.ai/code/session_01EG3WZSH3ZeTdAbb5T42r2w
2026-02-21 23:15:18 +00:00
cozis 964a029154 Add parallel transfer limit to client 2026-02-22 00:07:53 +01:00
Claude b0cc529773 Fix GET request returning corrupted data for multi-chunk blobs
Four bugs caused data mismatches between PUT and GET operations:

1. chunk_store_exists() used file_open (O_CREAT) to check if a chunk
   file exists, which created empty files as a side effect. Servers
   would then read from these empty files and return uninitialized
   heap memory as chunk data. Fixed by using file_exists (access())
   instead.

2. Server's process_fetch_chunk checked `ret < 0` after
   chunk_store_read, missing the EOF case (ret == 0) from empty
   files. Changed to `ret <= 0`.

3. begin_transfers() == 0 was used as a completion check in both
   STEP_FETCH_CHUNK and STEP_STORE_CHUNK, but returning 0 only means
   "no new transfers started", not "all done". With concurrent chunk
   transfers, this caused premature completion, leaving in-flight
   transfers to hit UNREACHABLE. Fixed by using
   all_chunk_transfers_completed() instead.

4. choose_store_locations_for_chunk() returned [0, 1] for ALL chunks
   regardless of index, while GET fetches chunk i from servers
   (i+j) % num_servers. This made some chunks unreachable. Fixed by
   using (chunk_idx + j) % num_servers for store locations.

Also added SO_REUSEADDR to the server listen socket so restarting
the cluster doesn't fail with "Couldn't setup TCP listener", and
added a note on mock_access about the simulation mismatch.

https://claude.ai/code/session_01JniNxxDP4NbsDXNGmGNG7H
2026-02-21 22:31:33 +00:00
Claude 8233392871 Fix client timeout propagation and add operation retry logic
The client library had several issues preventing operations from completing
in the simulation:

- toastyfs_register_events discarded the computed timeout instead of
  returning it to callers, so clients never woke up on schedule
- random_client_tick ignored the timeout parameter entirely
- deadline_to_timeout truncated sub-millisecond values to 0 instead of
  rounding up, causing busy-wait loops
- The server didn't reset the heartbeat timer after completing a view
  change, so followers would immediately timeout again
- The client's DELETE handler didn't handle META_RESULT_NOT_FOUND,
  causing an assertion failure when deleting non-existent keys
- Most critically, messages sent before TCP connections were established
  were silently dropped with no retry mechanism — added timeout-based
  retry logic in toastyfs_process_events

https://claude.ai/code/session_0184gHjra7fsmSPZ4kppaGhC
2026-02-21 14:08:07 +00:00
Claude 6e60b41f1b Add client trace lines and fix random client first-operation bug
Add logging infrastructure to client.c mirroring the server's node_log
pattern, with trace lines for: init, async put/get/delete, begin
transfers, replay requests, all received message types (store ack, fetch
chunk response, redirect, reply, get blob response), disconnects, and
unexpected messages.

Add result/operation trace lines to random_client.c and fix a bug where
the random client never started its first operation (the condition
`result.type != TOASTYFS_RESULT_VOID` was always false on the first
tick since no operation was pending).

https://claude.ai/code/session_0184gHjra7fsmSPZ4kppaGhC
2026-02-21 13:41:22 +00:00
Claude ab2ee3fe3b Add review feedback: SHA256 warning, MAX_TRANSFERS macro, CEIL macro, and TODO notes
- Add #warning to remind about replacing compute_chunk_hash with proper SHA256
- Define MAX_TRANSFERS and CEIL macros in config.h and use them
- Add TODO noting server selection formula is temporary
- Add NOTE about sticky error pattern in async functions
- Add TODO for INVALID_TIME error handling at all get_current_time call sites
- Add TODO about determining timeout based on pending operation status

https://claude.ai/code/session_01TkNavR4qyZcTuXMPmrtWUJ
2026-02-21 13:18:49 +00:00
Claude 723fc7cf76 Complete client library refactoring: fill all placeholders and implement missing functions
- Add REPLICATION_FACTOR and CHUNK_SIZE constants to config.h
- Add proper error codes (REJECTED, FULL, NOT_FOUND, TRANSFER_FAILED, etc.) to toastyfs.h
- Implement compute_chunk_hash() for deterministic chunk hashing
- Implement replay_request() to resend operations after leader redirect
- Implement send_message_to_server_ex() for sending messages with trailing data
- Implement choose_store_locations_for_chunk() to pick REPLICATION_FACTOR servers
- Fix begin_transfers() to handle both StoreChunk (PUT) and FetchChunk (GET)
- Complete toastyfs_async_put(): chunk splitting, hashing, data copy, metadata setup
- Complete toastyfs_async_get()/delete(): key setup, step/time initialization
- Fix get_result(): use actual transfer sizes instead of fixed chunk_size, free transfer data
- Replace all xxx placeholders and TOASTYFS_ERROR_XXX with proper values
- Add chunk_sizes[] tracking and put_data lifetime management
- Implement random_client.c: rng(), choose_random_oper(), proper API call arguments

https://claude.ai/code/session_01TkNavR4qyZcTuXMPmrtWUJ
2026-02-21 13:03:13 +00:00
Claude 78f2e5112b Apply code review feedback to client refactor
- Rename phase_time to step_time for consistency with Step enum
- Unify blob_size and file_size into single blob_size field
- Merge toastyfs_alloc into toastyfs_init, returning malloced ToastyFS*
- Replace (MessageHeader*)&msg casts with &msg.base
- Replace !resp.size with explicit resp.size == 0

https://claude.ai/code/session_018MRQTdAZoBCXJZgdP4U6V6
2026-02-21 11:54:21 +00:00
Claude 337cdad885 Fix test client refactor: broken includes, typos, and structural bugs
- Rename include/lib.h to include/toastyfs.h, add -Iinclude to build
- Fix build.sh: replace deleted blob_client.c with random_client.c
- Fix src/client.c: wrong include (client_lib.h), add missing STEP_FETCH_CHUNK
  enum, add missing struct fields (bucket, key, blob_size, content_hash,
  error, file_size, phase_time), fix TRANSFER_WAITING->TRANSFER_PENDING,
  fix begin_transfers() wrong variable refs, fix reap->resp typo,
  fix resp.size check inversion, fix state->tfs in process_events,
  fix tfs->transfer->tfs->transfers, fix tfs->phase->tfs->step,
  fix function name typos in toastyfs_get_result, fix async_put->async_get
  in toastyfs_get, fix ReplyMessage->RequestMessage in async_delete,
  fix put_result/delete_result return types, fix wait_until_result,
  add leader_idx() and toastyfs_alloc(), add missing MessageHeader casts
- Fix src/random_client.c: randm_client.h typo, addrs[i]->addrs[num_addrs],
  use toastyfs_alloc() for opaque type, fix tfs->state->tfs refs
- Fix src/random_client.h: wrong include guard names
- Fix src/main.c: replace deleted client.h/blob_client.h with
  random_client.h, update all client spawn configs to use RandomClient

https://claude.ai/code/session_018MRQTdAZoBCXJZgdP4U6V6
2026-02-21 11:46:01 +00:00
cozis 99b6c9dfcc Move files from lib/ into src/ and refactor the random client 2026-02-21 12:21:32 +01:00
cozis b64517c20e Full rewrite with VSR support 2026-02-20 16:55:29 +01:00
Claude cd3ecec786 Fix two bugs in read operation that caused test failure
1. Fix client not reading all server addresses in READ response
   The metadata server sends address info for ALL chunk servers holding
   a chunk, but the client only read info for ONE server. This caused
   message parsing to become misaligned for subsequent chunks.

   Added a loop to iterate through all num_servers and read each
   server's address list (using the first one, skipping the rest).

2. Fix tag value conflict between metadata and chunk server responses
   TAG_RETRIEVE_METADATA_FOR_READ was 1, which conflicted with chunk
   download range indices (0, 1, 2, 3...). When the second chunk
   download response came with range_idx=1, it was incorrectly treated
   as a metadata response.

   Changed TAG values from positive to negative integers since range
   indices are always non-negative.

Also updated the test to properly exit on success instead of assert(0).

https://claude.ai/code/session_01QYDQCNiUj1cjrsS6qRgkvd
2026-01-27 22:15:20 +00:00
cozis 3bb30dcd09 Implement pipe() mock 2026-01-27 22:57:45 +01:00
cozis 10053d3567 Add basic file creation, write, then read test and fix bug in tcp.c 2026-01-25 13:02:12 +01:00
cozis 31708d22cc Add feature testing build 2026-01-24 17:29:56 +01:00
Claude 8b5a5cb95e Handle allocation and I/O failures gracefully in simulation
Replace assert(0) with proper error handling for:
- malloc failures in client write operations
- binary_read failures during message parsing
- WAL append failures in metadata server
- Chunk server timeout (now drops unresponsive servers)

This fixes crashes exposed by fault injection testing.
2026-01-24 11:28:10 +00:00
Claude 3d44676a96 Fix upload tag overflow by increasing TAG_UPLOAD_CHUNK_MAX
The upload tag is computed as TAG_UPLOAD_CHUNK_MIN + upload_index, and the
assertion tag <= TAG_UPLOAD_CHUNK_MAX was failing when the number of uploads
exceeded 1000. This can happen with small chunk sizes (e.g., 1 byte) and
large writes, where each chunk needs multiple upload operations for
replication.

Increase TAG_UPLOAD_CHUNK_MAX from 2000 to 100000 to accommodate up to 99000
concurrent upload operations per write.
2026-01-24 01:13:59 +00:00
cozis 30c60d84df Bug fix 2026-01-23 20:57:14 +01:00
cozis 776f8c1015 Fix scheduling issue where time didn't advance if a host was always ready 2026-01-23 18:37:26 +01:00
cozis c10493881b Add Quakey 2026-01-16 14:45:09 +01:00
Claudeandcozis 6746b0d5fb Add MISSING_FILE_GENERATION special value for "file does not exist"
Implements a new special generation counter value (UINT64_MAX) that
allows clients to assert that a file should NOT exist when performing
operations.

Primary use case: Atomic "create-if-not-exists" operations
When combined with TOASTY_WRITE_CREATE_IF_MISSING flag:
- File doesn't exist → server creates file and writes (SUCCESS)
- File exists → gen_match fails → BADGEN error (prevents overwrite)

This enables race-condition-free file creation where you want to
create a NEW file or fail if it already exists.

Key changes:
- Added MISSING_FILE_GENERATION constant to file_tree.h
- Updated gen_match() to return false when checking existing entities
  against MISSING_FILE_GENERATION
- Modified file_tree_delete_entity() to succeed (no-op) when file is
  missing and MISSING_FILE_GENERATION is specified (idempotent delete)
- Modified file_tree_write() to validate against the new value
- Added documentation in metadata_server.c explaining how
  MISSING_FILE_GENERATION works WITH CREATE_IF_MISSING
- Updated protocol documentation in PROTOCOL.txt
- Added comprehensive feature documentation in MISSING_FILE_GENERATION.md

Additional use cases:
- Idempotent delete operations (delete only if not already gone)
- Detecting unexpected file creation in validation/testing scenarios

The implementation is backward compatible and type-safe. Files are
never assigned MISSING_FILE_GENERATION as their actual generation value.
2025-12-05 09:10:17 +01:00
cozis e73bb3a7d8 Add crash logger 2025-12-04 12:25:19 +01:00
Claude 8160c5ac51 Add TOASTY_WRITE_CREATE_IF_MISSING flag for server-side file auto-creation
Adds support for automatically creating files when write operations target
non-existent files. This is essential for REST PUT operations which should
be able to create new resources.

Implementation:
- Added TOASTY_WRITE_CREATE_IF_MISSING flag to ToastyFS API header
- Updated toasty_write() and toasty_begin_write() to accept flags parameter
- Client sends write flags in MESSAGE_TYPE_WRITE message to metadata server
- Metadata server parses flags and handles file auto-creation atomically:
  * When write fails with FILETREE_NOENT and flag is set
  * Logs creation to WAL for crash consistency
  * Creates file with default 4096-byte chunk size
  * Retries write with newly created file's generation tag
- Updated web proxy PUT handler to use TOASTY_WRITE_CREATE_IF_MISSING
- Updated examples and simulation client for new API signature

Benefits:
- Works for both sync and async APIs
- Single round trip (atomic server-side operation)
- Prevents race conditions
- Proper WAL logging ensures crash consistency
2025-12-03 18:48:42 +00:00
cozis 0d099a1fa6 Return version tags in directory listing 2025-11-25 12:08:33 +01:00
cozis afad13f44f Allow users of libtoastyfs to operate on files/directories with specific version tags 2025-11-24 14:34:57 +01:00
Claude acb1336d47 Implement synchronization protocol from PROTOCOL.txt
Updated both client.c and metadata_server.c to match the protocol
specification in misc/PROTOCOL.txt:

Client-to-Server Messages:
- Added expect_gen field to DELETE, LIST, READ, and WRITE messages
- Removed old_hash and chunk_size from WRITE message chunks

Server-to-Client Responses:
- Added generation counter to CREATE_SUCCESS response
- Added generation counter to LIST_SUCCESS response
- Fixed LIST_SUCCESS field order (gen, truncated, item_count)
- Added generation counter to READ_SUCCESS response
- Added generation counter to WRITE_SUCCESS response

All changes compile successfully and pass valgrind memory checks.
2025-11-24 12:16:55 +00:00
cozis d7a2262172 Fix compilation errors of the web interface 2025-11-22 23:59:08 +01:00
Claude f856bd0e05 Track actual bytes read in read operations
Add functionality to determine the actual number of bytes read during
read operations, making it possible to detect when a read was truncated
because it went past the end of the file.

Changes:
- Modified file_tree_read() to calculate and return actual_bytes via
  new output parameter
- Updated metadata server to send actual_bytes in READ_SUCCESS messages
- Added bytes_read field to ToastyResult structure
- Modified client to parse, store, and report actual bytes read
- Updated toasty_read() to return the actual number of bytes read
  instead of always returning 0
- Fixed web server to use bytes_read field instead of non-existent
  count field

This allows clients to distinguish between:
- Reading zeros because the file is sparse (has holes)
- Reading past the end of the file (truncated read)
2025-11-22 22:22:43 +00:00
cozis b930ba08e3 Add the ability to associate an opaque user pointer to a ToastyHandle which is then returned in its associated ToastyResult 2025-11-22 23:09:31 +01:00
cozis e1fa3729c6 Drop the MAX_CONNS macro and define TCP_CONNECTION_LIMIT, TCP_POLL_CAPACITY, TCP_EVENT_CAPACITY instead 2025-11-22 22:59:32 +01:00
cozis 747f851155 Draft of the REST server client using cHTTP 2025-11-20 10:50:55 +01:00
cozis b0313ffcf8 Make toasty client thread-safe and implement toasty_wakeup 2025-11-20 03:51:01 +01:00
cozis 46db334a2e Resolve compilation errors and implement blocking API 2025-11-17 11:32:09 +01:00
cozis ee05547981 Fix compilation errors 2025-11-16 16:16:54 +01:00
cozis c6cac0155e Change client.c to match the new ToastyFS.h API 2025-11-16 16:07:03 +01:00
cozis b591408cc9 Fix some build errors 2025-11-16 13:01:08 +01:00
cozis 914419df6d Add timeout logic to toastyfs_wait 2025-11-16 11:59:39 +01:00
cozis e1cdc28d4d Rename project to ToastyFS 2025-11-16 02:10:59 +01:00
cozis a366b46398 Bug fixes 2025-11-15 10:38:45 +01:00
Claude 1a297989d4 Rename project from TinyDFS to MouseFS
- Renamed TinyDFS.h to MouseFS.h
- Updated all type names: TinyDFS -> MouseFS, TinyDFS_Entity -> MouseFS_Entity, TinyDFS_Result -> MouseFS_Result
- Updated all enum values: TINYDFS_RESULT_* -> MOUSEFS_RESULT_*
- Updated all function names: tinydfs_* -> mousefs_*
- Updated all variable names: tdfs -> mfs
- Updated references in all source files, headers, examples, and documentation
- Updated Makefile build targets: tinydfs_* -> mousefs_*
2025-11-10 18:00:05 +00:00
cozis d25d79c1f1 Clean up state update logic in chunk server 2025-11-10 18:36:11 +01:00
cozis 8ea71ac236 Fix bug in client 2025-11-10 16:03:16 +01:00
cozis 9cdf636eb6 Bug fix 2025-11-10 12:41:18 +01:00
cozis bab8558511 Progress 2025-11-09 20:36:08 +01:00
cozis d13ad3ae6c Progress 2025-11-09 19:43:24 +01:00
cozis ecef79cc53 Progress 2025-11-09 19:06:23 +01:00
cozis bf1a18b9d0 Progress 2025-11-09 18:19:17 +01:00