Browse Source

Track current active filer in FilerClient for better HA

Add GetCurrentFiler() method to FilerClient that returns the currently
active filer based on the filerIndex which is updated on successful
operations. This provides better availability than always using the
first filer.

Changes:
- Add FilerClient.GetCurrentFiler() method that returns current active filer
- Update S3ApiServer.getFilerAddress() to use FilerClient's current filer
- Add fallback to first filer if FilerClient not yet initialized
- Document IAM limitation (doesn't have FilerClient access)

Benefits:
- Single-filer operations (URLs, ReadFilerConf, etc.) now use the
  currently active/healthy filer
- Better distribution and failover behavior
- FilerClient's round-robin and health tracking automatically
  determines which filer to use
pull/7550/head
Chris Lu 4 days ago
parent
commit
ee6054700f
  1. 3
      weed/iamapi/iamapi_server.go
  2. 10
      weed/s3api/s3api_server.go
  3. 20
      weed/wdclient/filer_client.go

3
weed/iamapi/iamapi_server.go

@ -39,7 +39,8 @@ type IamS3ApiConfigure struct {
}
// getFilerAddress returns the current filer address to use
// Returns the first filer for single-address operations
// Note: IAM operations don't have access to FilerClient's current filer tracking
// Returns the first filer as fallback - consider adding FilerClient to IamS3ApiConfigure
func (iama *IamS3ApiConfigure) getFilerAddress() pb.ServerAddress {
if len(iama.option.Filers) > 0 {
return iama.option.Filers[0]

10
weed/s3api/s3api_server.go

@ -185,10 +185,14 @@ func NewS3ApiServerWithStore(router *mux.Router, option *S3ApiServerOption, expl
return s3ApiServer, nil
}
// getFilerAddress returns the current filer address to use
// For operations that need a single address, returns the first one
// The underlying FilerClient handles failover automatically
// getFilerAddress returns the current active filer address
// Uses FilerClient's tracked current filer which is updated on successful operations
// This provides better availability than always using the first filer
func (s3a *S3ApiServer) getFilerAddress() pb.ServerAddress {
if s3a.filerClient != nil {
return s3a.filerClient.GetCurrentFiler()
}
// Fallback to first filer if filerClient not initialized
if len(s3a.option.Filers) > 0 {
return s3a.option.Filers[0]
}

20
weed/wdclient/filer_client.go

@ -184,6 +184,26 @@ func NewFilerClient(filerAddresses []pb.ServerAddress, grpcDialOption grpc.DialO
return fc
}
// GetCurrentFiler returns the currently active filer address
// This is the filer that was last successfully used or the one indicated by round-robin
// Returns empty string if no filers are configured
func (fc *FilerClient) GetCurrentFiler() pb.ServerAddress {
fc.filerAddressesMu.RLock()
defer fc.filerAddressesMu.RUnlock()
if len(fc.filerAddresses) == 0 {
return ""
}
// Get current index (atomically updated on successful operations)
index := atomic.LoadInt32(&fc.filerIndex)
if index >= int32(len(fc.filerAddresses)) {
index = 0
}
return fc.filerAddresses[index]
}
// Close stops the filer discovery goroutine if running
func (fc *FilerClient) Close() {
if fc.stopDiscovery != nil {

Loading…
Cancel
Save