diff --git a/weed/iamapi/iamapi_server.go b/weed/iamapi/iamapi_server.go index 11005d00c..cb6712f29 100644 --- a/weed/iamapi/iamapi_server.go +++ b/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] diff --git a/weed/s3api/s3api_server.go b/weed/s3api/s3api_server.go index 4b658525a..d29bf5ff2 100644 --- a/weed/s3api/s3api_server.go +++ b/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] } diff --git a/weed/wdclient/filer_client.go b/weed/wdclient/filer_client.go index 820a346c5..7e6b0b07a 100644 --- a/weed/wdclient/filer_client.go +++ b/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 {