mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-02 14:17:19 +00:00
* filer: add a placement overlay seam for the write path New volumes take their disk type, replication, and data center from the explicit request or the matched filer.conf rule. That leaves no way for a feature to steer a whole collection onto a medium without an operator writing an fs.configure rule by hand. Add a generic PlacementOverlay hook on the filer: a func that maps a collection to a placement override, installed by a factory the way the plugin-worker handlers register. detectStorageOption consults it between the explicit request value and the filer.conf rule, so it overrides the rule but yields to a value the caller asked for. The seam names no feature concepts, so it stays generic; a downstream build registers the overlay it wants (e.g. a storage-class Landing tier). Claude-Session: https://claude.ai/code/session_01Ks16jnt4S7gdDk8cheQ3xu * filer: address review on the placement overlay seam Honor ResolvePlacement's ok flag explicitly rather than relying on empty values falling through the util.Nvl chain, and log at V(4) when the overlay steers a collection. Document that RegisterPlacementOverlay is init-only, so the unsynchronized read in NewFiler cannot race the write. Claude-Session: https://claude.ai/code/session_01Ks16jnt4S7gdDk8cheQ3xu
37 lines
1.9 KiB
Go
37 lines
1.9 KiB
Go
package filer
|
|
|
|
// PlacementOverlay resolves a write-time placement override for a collection —
|
|
// the disk type, replication, and data center new volumes of that collection
|
|
// should land on — or ok=false when the collection has none.
|
|
//
|
|
// It exists so a feature can steer where a bound collection's data lands without
|
|
// every operator setting an fs.configure rule by hand. The type is deliberately
|
|
// generic: it names no placement-policy concepts, so a downstream build
|
|
// registers whatever overlay it wants without coupling this seam to it.
|
|
type PlacementOverlay func(collection string) (diskType, replication, dataCenter string, ok bool)
|
|
|
|
// newPlacementOverlay builds the overlay for a filer. Enterprise sets it in an
|
|
// init() pulled in by a side-effect import, the way plugin-worker handlers
|
|
// register — the setter cannot live here because this package is overwritten by
|
|
// the sync.
|
|
var newPlacementOverlay func(*Filer) PlacementOverlay
|
|
|
|
// RegisterPlacementOverlay installs the factory. It is meant to be called from a
|
|
// package init() — before any Filer is constructed and before serving starts —
|
|
// so the unsynchronized read in NewFiler never races the write. The last
|
|
// registration wins; there is only ever one overlay.
|
|
func RegisterPlacementOverlay(factory func(*Filer) PlacementOverlay) {
|
|
newPlacementOverlay = factory
|
|
}
|
|
|
|
// ResolvePlacement returns the overlay's placement for a collection, or
|
|
// ok=false when there is no overlay or the collection is not steered. The write
|
|
// path applies these between the explicit request value and the filer.conf
|
|
// rule, so an overlay overrides the rule but yields to an explicit request.
|
|
func (f *Filer) ResolvePlacement(collection string) (diskType, replication, dataCenter string, ok bool) {
|
|
if f == nil || f.placementOverlay == nil || collection == "" {
|
|
return "", "", "", false
|
|
}
|
|
return f.placementOverlay(collection)
|
|
}
|