diff options
| author | Bernhard Guillon <Bernhard.Guillon@begu.org> | 2026-07-07 09:20:10 +0200 |
|---|---|---|
| committer | Bernhard Guillon <Bernhard.Guillon@begu.org> | 2026-07-07 09:20:10 +0200 |
| commit | 0642028735adcb2d431e5e146ca87accb4954900 (patch) | |
| tree | 882c17b457539239e36f6a27b803e391d66cba6e /types.go | |
| parent | a0d157d45c5b4c63afc2cfc82bde3ae3207bc455 (diff) | |
| download | sourcewatch-0642028735adcb2d431e5e146ca87accb4954900.tar.gz sourcewatch-0642028735adcb2d431e5e146ca87accb4954900.zip | |
Add Windows-assisted initial sync for faster startup
New protocol:
- Windows binary scans directory (fast native NTFS) and sends manifest
- Container receives manifest, compares with local /data state
- Only copies files that differ (size, modtime, mode, symlink)
Protocol messages:
- manifest: sends full file metadata from Windows
- manifest_done: signals manifest transfer complete
- event_create/write/remove: file change events
Flow:
1. Container connects to socket
2. Windows binary sends manifest (file metadata)
3. Container scans /data (fast local volume)
4. Container copies only changed files from /host (9P bind mount)
5. Container enters event-waiting loop
This dramatically speeds up initial sync by avoiding slow 9P scans.
Diffstat (limited to 'types.go')
| -rw-r--r-- | types.go | 54 |
1 files changed, 54 insertions, 0 deletions
@@ -1,6 +1,7 @@ package main import ( + "encoding/json" "os" "time" ) @@ -18,6 +19,59 @@ type FileMeta struct { Symlink string } +type FileMetaJSON struct { + Size int64 `json:"size"` + Mode uint32 `json:"mode"` + ModTime string `json:"modtime"` + Symlink string `json:"symlink,omitempty"` +} + type Manifest struct { Files map[string]FileMeta } + +type ProtocolMessage struct { + Type string `json:"type"` + Files map[string]FileMetaJSON `json:"files,omitempty"` + Path string `json:"path,omitempty"` + Content []byte `json:"content,omitempty"` +} + +func (m *Manifest) ToJSON() map[string]FileMetaJSON { + files := make(map[string]FileMetaJSON, len(m.Files)) + for k, v := range m.Files { + files[k] = FileMetaJSON{ + Size: v.Size, + Mode: uint32(v.Mode), + ModTime: v.ModTime.UTC().Format(time.RFC3339Nano), + Symlink: v.Symlink, + } + } + return files +} + +func ManifestFromJSON(files map[string]FileMetaJSON) *Manifest { + m := &Manifest{Files: make(map[string]FileMeta, len(files))} + for k, v := range files { + t, _ := time.Parse(time.RFC3339Nano, v.ModTime) + m.Files[k] = FileMeta{ + Size: v.Size, + Mode: os.FileMode(v.Mode), + ModTime: t, + Symlink: v.Symlink, + } + } + return m +} + +func DecodeMessage(data []byte) (*ProtocolMessage, error) { + var msg ProtocolMessage + if err := json.Unmarshal(data, &msg); err != nil { + return nil, err + } + return &msg, nil +} + +func EncodeMessage(msg *ProtocolMessage) ([]byte, error) { + return json.Marshal(msg) +} |
