feat: persist.c WAL writer with chained CRC32 and dedicated fsync pthread (P0-1)
- Expose persist_t struct concretely in persist.h (opaque pattern deferred) - persist_set_workdir() derives wal/snap paths from workdir+name - persist_init() creates WAL/snap directories, rejects NFS mounts - persist_wal_async() writes WAL entries with chained CRC32 via zlib - Dedicated fsync pthread fires every wal_sync_ms milliseconds - persist_flush() forces fdatasync for tests and clean shutdown - WAL_CHECKPOINT type rejected with -EINVAL (never written via async path) - Stubs: persist_recover, persist_wal_sync_append, persist_checkpoint - Add fsync_thread_running flag to guard persist_stop when thread not started - Add zlib_dep to controller and unit test meson targets - 3 new TDD tests: init_creates_directories, wal_async_writes_entry, checkpoint_type_rejected — all GREEN
This commit is contained in:
parent
d66a8a98b6
commit
b0a5fbb4e9
5 changed files with 502 additions and 2 deletions
|
|
@ -81,10 +81,48 @@ typedef struct {
|
|||
} slot_key_t;
|
||||
|
||||
/* ============================================================
|
||||
* persist_t — opaque; defined in persist.c (Task 7)
|
||||
* persist_t — concrete definition (exposed for stack/calloc allocation)
|
||||
* The opaque pattern can be restored in a later refactor once the
|
||||
* full API surface is stable.
|
||||
* ============================================================ */
|
||||
struct persist_s {
|
||||
/* WAL state */
|
||||
int wal_fd;
|
||||
uint64_t current_lsn;
|
||||
uint64_t last_crc;
|
||||
uint64_t last_replicated_crc;
|
||||
uint64_t term;
|
||||
uint32_t seg_offset;
|
||||
uint64_t checkpoint_lsn;
|
||||
uint64_t total_wal_bytes;
|
||||
char seg_path[4096];
|
||||
|
||||
/* Paths (derived from workdir + name via persist_set_workdir) */
|
||||
char wal_path[4096];
|
||||
char snap_path[4096];
|
||||
|
||||
/* Config */
|
||||
persist_config_t config;
|
||||
|
||||
/* Concurrency */
|
||||
pthread_mutex_t lock;
|
||||
atomic_int fsync_stop;
|
||||
atomic_int fsync_thread_running;
|
||||
pthread_t fsync_thread;
|
||||
|
||||
/* Checkpoint (stubs for now — wired in Task 10) */
|
||||
atomic_int checkpoint_in_progress;
|
||||
atomic_int checkpoint_requested;
|
||||
pthread_cond_t checkpoint_done;
|
||||
pthread_mutex_t checkpoint_mutex;
|
||||
pthread_t snap_thread;
|
||||
};
|
||||
typedef struct persist_s persist_t;
|
||||
|
||||
/* Set workdir and controller name before persist_init().
|
||||
* Derives wal_path and snap_path as <workdir>/<name>/data/{wal,snap}. */
|
||||
void persist_set_workdir(persist_t* p, const char* workdir, const char* name);
|
||||
|
||||
/* Lifecycle */
|
||||
int persist_init(persist_t* p, persist_config_t* config, cluster_t* c);
|
||||
int persist_start(persist_t* p);
|
||||
|
|
@ -99,6 +137,9 @@ int persist_wal_sync_append(persist_t* p, uint32_t type,
|
|||
const void* payload, uint32_t len,
|
||||
int* sync_rc_out);
|
||||
|
||||
/* Force WAL fdatasync (for tests and clean shutdown) */
|
||||
int persist_flush(persist_t* p);
|
||||
|
||||
/* Checkpoint */
|
||||
int persist_checkpoint(persist_t* p);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue