Class TransferServerProvider
TransferServer instances in ECPDS. The provider is responsible
for multi-level load distribution: cluster-level weighted round-robin (WRR), per-group server rotation, and
storage-volume-aware allocation.
Scheduling Layers
- Group resolution: The provider resolves a
TransferGroupfrom explicit name, destination mapping, or default configuration. - Cluster WRR: If enabled by construction semantics, a group within the same cluster can be chosen via WRR. The RR counter resets on topology changes (weights / activation / availability) to avoid skew.
- Volume allocation: The selected group’s volume index is chosen either explicitly (pre-allocated) or via
TransferServerProvider.WeightedAllocator, with optional size-aware penalties and CV-based uniform fallback. - Server ordering: Within the group, active and reachable DataMovers are ordered by least filesystem activity on the selected volume, with caller-stable rotation as a tie-breaker. A preferred server, if provided, is reinserted at index 0.
State invalid input: '&' Caches
- Instances are immutable w.r.t. selected group, volume index, and server ordering.
- Static caches maintain cluster RR state, per-group RR counters, volume usage, and allocator statistics.
- A background daemon refreshes volume usage and mover ordering.
Thread Safety
- All public methods are read-only and safe for concurrent calls.
- Static schedulers use
ConcurrentHashMapand atomics. - Allocator uses per-group locking for consistent snapshots.
Failure Semantics
- Provider construction fails fast if the group is unavailable, has no volumes, or if no active DataMover is selectable.
- Destination/group lookup errors propagate as
TransferServerProvider.TransferServerExceptionorDataBaseException.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final classException indicating that a suitable transfer group or server could not be found or selected. -
Constructor Summary
ConstructorsConstructorDescriptionTransferServerProvider(String caller, String groupName) Convenience constructor that delegates to the canonical constructor with:destinationName = nullfileSize = -1server = nullallocatedFileSystem = nullSeeTransferServerProvider(String, String, String, long, TransferServer, Integer)for detailed behaviour.TransferServerProvider(String caller, String groupName, String destination) Convenience constructor that delegates to the canonical constructor with:fileSize = -1server = nullallocatedFileSystem = nullSeeTransferServerProvider(String, String, String, long, TransferServer, Integer)for detailed behaviour.TransferServerProvider(String caller, String groupName, String destination, long fileSize) Convenience constructor that delegates to the canonical constructor with:server = nullallocatedFileSystem = nullSeeTransferServerProvider(String, String, String, long, TransferServer, Integer)for detailed behaviour.TransferServerProvider(String caller, String groupName, String destinationName, long fileSize, TransferServer server, Integer allocatedFileSystem) Constructs a provider and pre-computes: theTransferGroupto use (explicit, destination-mapped, or default; may be adjusted within the cluster by WRR fallback), the storage volume index (getFileSystem()), using either an explicit index or theTransferServerProvider.WeightedAllocator, the orderedTransferServerlist according to the least-activity policy (FS activity primary; rotation tie-breaker; optional preferred server on top).TransferServerProvider(String caller, String groupName, String destination, TransferServer server, Integer allocatedFileSystem) Convenience constructor that delegates to the canonical constructor with:fileSize = -1(disables size-aware allocation) SeeTransferServerProvider(String, String, String, long, TransferServer, Integer)for detailed behaviour.TransferServerProvider(String caller, String groupName, String destination, Integer allocatedFileSystem) Convenience constructor that delegates to the canonical constructor with:fileSize = -1(disables size‑aware volume allocation)server = null(no preferred server to reinsert)allocatedFileSystemexplicitly provided by the caller -
Method Summary
Modifier and TypeMethodDescriptionintHow the index is obtained:Returns the resolved and validatedTransferGroupfor this provider instance.Convenience accessor forgetTransferGroup().getName().Returns a snapshot of the activeTransferServerlist for this provider instance, ordered by the “least activity” policy that was computed during construction.Returns the activeTransferServerlist ordered by highest free space on the selected volume (getFileSystem()), if a cache entry is available.getVolumeSnapshot(String groupName) Returns a snapshot of the current volume disk usage for all registered transfer groups, or for a single group ifgroupNameis non-null.
-
Constructor Details
-
TransferServerProvider
public TransferServerProvider(String caller, String groupName, String destination, long fileSize) throws TransferServerProvider.TransferServerException, DataBaseException Convenience constructor that delegates to the canonical constructor with:server = nullallocatedFileSystem = null
TransferServerProvider(String, String, String, long, TransferServer, Integer)for detailed behaviour.- Parameters:
caller- identifier of the caller (used for stable rotation seeding)groupName- explicit group name; ifnull,destinationand/or default are useddestination- optional destination name used for group resolutionfileSize- expected file size in bytes (non-positive disables size-aware allocation)- Throws:
TransferServerProvider.TransferServerException- if no suitable group/server can be selectedDataBaseException- on database errors
-
TransferServerProvider
public TransferServerProvider(String caller, String groupName, String destination, TransferServer server, Integer allocatedFileSystem) throws TransferServerProvider.TransferServerException, DataBaseException Convenience constructor that delegates to the canonical constructor with:fileSize = -1(disables size-aware allocation)
TransferServerProvider(String, String, String, long, TransferServer, Integer)for detailed behaviour.- Parameters:
caller- identifier of the caller (used for stable rotation seeding)groupName- explicit group name; ifnull,destinationand/or default are useddestination- optional destination name used for group resolutionserver- optional preferred server to reinsert at index 0 if active/reachableallocatedFileSystem- optional explicit volume index; whennull, the allocator is used- Throws:
TransferServerProvider.TransferServerException- if no suitable group/server can be selectedDataBaseException- on database errors
-
TransferServerProvider
public TransferServerProvider(String caller, String groupName, String destination) throws TransferServerProvider.TransferServerException, DataBaseException Convenience constructor that delegates to the canonical constructor with:fileSize = -1server = nullallocatedFileSystem = null
TransferServerProvider(String, String, String, long, TransferServer, Integer)for detailed behaviour.- Parameters:
caller- identifier of the caller (used for stable rotation seeding)groupName- explicit group name; ifnull,destinationand/or default are useddestination- optional destination name used for group resolution- Throws:
TransferServerProvider.TransferServerException- if no suitable group/server can be selectedDataBaseException- on database errors
-
TransferServerProvider
public TransferServerProvider(String caller, String groupName, String destination, Integer allocatedFileSystem) throws TransferServerProvider.TransferServerException, DataBaseException Convenience constructor that delegates to the canonical constructor with:fileSize = -1(disables size‑aware volume allocation)server = null(no preferred server to reinsert)allocatedFileSystemexplicitly provided by the caller
This overload is used when the caller wants to:
- select a specific transfer group (via
groupNameor destination lookup), - optionally resolve the group based on
destination, - force the use of a specific storage volume index (bypassing weighted allocation),
- and does not wish to use size‑aware volume selection.
The behaviour of group resolution, availability checks, and cluster‑level fallback follows the rules documented in the canonical constructor
TransferServerProvider(String, String, String, long, TransferServer, Integer).- Parameters:
caller- identifier of the caller (used for stable rotation seeding)groupName- explicit group name; ifnull, group is resolved fromdestinationor configurationdestination- optional destination used for group resolutionallocatedFileSystem- explicit volume index to use instead of weighted allocation- Throws:
TransferServerProvider.TransferServerException- if the resolved/selected group is not available, has no volumes, or if no active DataMover can be selectedDataBaseException- if database queries for group, destination, or servers fail
-
TransferServerProvider
public TransferServerProvider(String caller, String groupName) throws TransferServerProvider.TransferServerException, DataBaseException Convenience constructor that delegates to the canonical constructor with:destinationName = nullfileSize = -1server = nullallocatedFileSystem = null
TransferServerProvider(String, String, String, long, TransferServer, Integer)for detailed behaviour.- Parameters:
caller- identifier of the caller (used for stable rotation seeding)groupName- explicit group name; ifnull, the default is used- Throws:
TransferServerProvider.TransferServerException- if no suitable group/server can be selectedDataBaseException- on database errors
-
TransferServerProvider
public TransferServerProvider(String caller, String groupName, String destinationName, long fileSize, TransferServer server, Integer allocatedFileSystem) throws TransferServerProvider.TransferServerException, DataBaseException Constructs a provider and pre-computes:- the
TransferGroupto use (explicit, destination-mapped, or default; may be adjusted within the cluster by WRR fallback), - the storage volume index (
getFileSystem()), using either an explicit index or theTransferServerProvider.WeightedAllocator, - the ordered
TransferServerlist according to the least-activity policy (FS activity primary; rotation tie-breaker; optional preferred server on top).
Group resolution invalid input: '&' fallback: The constructor first resolves the group via
resolveTransferGroup(String, String). IfallocatedFileSystemisnullor if the resolved group is not available, it may select a different group within the same cluster usingtryClusterFallback(TransferGroup), which in turn leverages cluster-wide WRR throughselectGroupFromClusterRoundRobin(TransferGroup, TransferGroup[]).Volume selection: If
allocatedFileSystemis non-null, it is used as-is. Otherwise, theTransferServerProvider.WeightedAllocatoris invoked:- when
fileSize > 0,TransferServerProvider.WeightedAllocator.allocate(TransferGroup, long)is used; - otherwise,
TransferServerProvider.WeightedAllocator.allocate(TransferGroup)is used.
Server ordering: The final least-activity ordering is computed once during construction via
computeLeastActivityOrdering(String, TransferGroup, TransferServer, int). If the resulting active list is empty, construction fails.Thread-safety: The constructed instance is immutable with respect to selection decisions (group, volume index, server ordering). Static caches and background updaters are concurrency-safe.
- Parameters:
caller- identifier of the caller (used for stable rotation seeding)groupName- explicit group name; ifnull,destinationNameand/or the global default are useddestinationName- optional destination used for group resolution (seeresolveTransferGroup(String, String))fileSize- expected file size in bytes; non-positive values disable size-aware allocationserver- optional preferred server to reinsert at index 0 if active/reachableallocatedFileSystem- optional explicit volume index; whennull, the allocator is used- Throws:
TransferServerProvider.TransferServerException- if the resolved/selected group is not available, has no volumes, or if no active DataMover can be selectedDataBaseException- if the database lookups fail for group, destination, or servers
- the
-
-
Method Details
-
getVolumeSnapshot
Returns a snapshot of the current volume disk usage for all registered transfer groups, or for a single group ifgroupNameis non-null.Delegates to
TransferServerProvider.WeightedAllocator.getVolumeSnapshot(String). The data comes from the in-memory cache maintained by the background usage updater — no DataMover RMI calls are made at query time.- Parameters:
groupName- the transfer group to query, ornullfor all groups- Returns:
- a map of group name to
long[volumeIndex][2]where[i][0]is used bytes and[i][1]is total bytes; nevernull; empty if no data has been collected yet
-
getFileSystem
public int getFileSystem()How the index is obtained:
- If the caller provided an explicit
allocatedFileSystemin the constructor, that exact index is used. - Otherwise, the index is selected during construction by the
TransferServerProvider.WeightedAllocator, using either size-aware weights (when a positivefileSizeis given) or free-space weights.
This value is immutable for the lifetime of this provider instance and is guaranteed to be within
[0, group.getVolumeCount()).- Returns:
- the selected (0-based) volume index for this provider instance
- If the caller provided an explicit
-
getTransferGroup
Returns the resolved and validatedTransferGroupfor this provider instance.The group is resolved at construction time using (in order):
- Explicit
groupName, if provided - Destination mapping (if a
destinationNamewas provided) - Global default transfer group (from configuration)
After resolution, the provider may switch to a different group within the same cluster through WRR-based fallback if either:
- the resolved group is not currently available, or
- no explicit
allocatedFileSystemwas provided and cluster selection is enabled
The returned group is guaranteed to be
activeand to have at least one active/connectedDataMoverat the time of construction; otherwise construction fails.- Returns:
- the selected and available
TransferGroup; nevernull
- Explicit
-
getTransferGroupName
Convenience accessor forgetTransferGroup().getName().Equivalent to
getTransferGroup().getName(), provided for call sites that only need the name.- Returns:
- the name of the selected transfer group; never
null
-
getTransferServersByLeastActivity
Returns a snapshot of the activeTransferServerlist for this provider instance, ordered by the “least activity” policy that was computed during construction.Ordering policy (computed at construction time):
- Caller-stable base rotation (deterministic hash of
caller, group name, and runtime salt) combined with a per-group round-robin counter to mitigate burst skew. - Filtering of inactive or unreachable servers (only active servers with a reachable
DataMoverinterface remain). - Primary sort by per-volume activity: servers with the fewest downloads on
getFileSystem()come first. - Tie-breaker by rotation order: among equal loads, the rotated declared order decides.
- If a preferred server was provided to the constructor and is available, it is reinserted at index 0.
The returned list is an independent copy and can be freely modified by the caller. Subsequent calls return a fresh copy of the same internal ordering (the provider does not recompute ordering after construction).
Thread-safety: This method performs no mutation and is safe for concurrent calls. The underlying ordering is immutable within this provider instance.
- Returns:
- a new
Listof activeTransferServerinstances, ordered by least activity
- Caller-stable base rotation (deterministic hash of
-
getTransferServersByMostFreeSpace
Returns the activeTransferServerlist ordered by highest free space on the selected volume (getFileSystem()), if a cache entry is available.Behaviour:
- If a
VolumeUsageResultis present in the internal cache forgroupName + ":" + fileSystem, the method uses the mover ordering computed byMasterServer.computeAllVolumeUsageAndMovers(TransferGroup)(descending free space), intersected with the provider's active set. - If no cache entry exists, the method returns a shuffled copy of the provider's least-activity list as a best-effort fallback to avoid persistent hot-spotting.
Scope: This method does not modify the provider's internal least-activity ordering; it returns a new list each time. The cache is populated asynchronously by the background usage updater.
Thread-safety: Safe for concurrent callers; relies on immutable snapshots and concurrent maps.
- Returns:
- a new
Listof activeTransferServerinstances sorted by descending free space on the selected volume when cache is present; otherwise a shuffled best-effort ordering
- If a
-