syntax = "proto3"; package mount_peer_pb; option go_package = "github.com/seaweedfs/seaweedfs/weed/pb/mount_peer_pb"; ////////////////////////////////////////////////// // Peer chunk sharing — mount-to-mount chunk directory // // Each weed mount exposes this service on its -peer.listen address. // Ownership of fid -> holders tracking is sharded across the mount fleet // via rendezvous (HRW) hashing on the registered mount list. See // design-weed-mount-peer-chunk-sharing.md for protocol details. ////////////////////////////////////////////////// service MountPeer { // ChunkAnnounce: the caller asserts it currently holds the listed fids in // its local chunk cache and is willing to serve them to peers. The // receiver accepts only fids for which it is the HRW-assigned owner on // its current seed view; others are returned in rejected_file_ids. rpc ChunkAnnounce (ChunkAnnounceRequest) returns (ChunkAnnounceResponse) { } // ChunkLookup: asks the receiver for known holders of each requested fid. // The receiver responds only for fids it owns; others are listed in // not_owner_file_ids so the caller can retry against the correct owner // after refreshing its own seed view. rpc ChunkLookup (ChunkLookupRequest) returns (ChunkLookupResponse) { } // FetchChunk: server-streams the bytes of a cached chunk to a peer. // Streaming avoids the default gRPC 4 MiB message cap for typical // 16 MiB chunks and lets the receiver assemble into a preallocated // buffer. Not-cached / cache-miss returns a gRPC NOT_FOUND status. // The fetcher re-verifies MD5 against expected_etag end-to-end after // the stream completes. rpc FetchChunk (FetchChunkRequest) returns (stream FetchChunkResponse) { } } message ChunkAnnounceRequest { repeated string file_ids = 1; string peer_addr = 2; string rack = 3; int32 ttl_seconds = 4; string data_center = 5; } message ChunkAnnounceResponse { repeated string rejected_file_ids = 1; // receiver is not the owner of these fids } message ChunkLookupRequest { repeated string file_ids = 1; } message ChunkLookupResponse { map peers_by_fid = 1; repeated string not_owner_file_ids = 2; } message PeerSet { repeated PeerInfo peers = 1; } message PeerInfo { string peer_addr = 1; string rack = 2; string data_center = 3; } message FetchChunkRequest { string file_id = 1; string expected_etag = 2; // caller's expected MD5 over the FULL chunk. // Only meaningful when offset=0 and length=0 // (a whole-chunk fetch); partial reads can't // be verified against a whole-chunk MD5. // Fetcher re-verifies end-to-end. uint64 expected_size = 3; // filer-reported chunk byte count; server sizes // its cache-read buffer to exactly this so a // sub-max-part-size chunk doesn't trigger the // cache wrapper's all-or-nothing miss path. uint64 offset = 4; // optional: byte offset within the chunk to // start reading from. 0 (default) means a // whole-chunk transfer starting at byte zero. uint64 length = 5; // optional: number of bytes to return from // offset. 0 (default) means "until end of // chunk". Range is capped server-side by // maxFetchChunkBytes regardless. } message FetchChunkResponse { bytes data = 1; // next frame of chunk bytes; concatenate across stream }