| File: Routing\Internal\WeightedGroups\WeightedGroupsRoutingStrategy.cs | Web Access |
| Project: src\src\Libraries\Microsoft.Extensions.Http.Resilience\Microsoft.Extensions.Http.Resilience.csproj (Microsoft.Extensions.Http.Resilience) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using Microsoft.Extensions.Http.Resilience.Internal; using Microsoft.Extensions.ObjectPool; using Microsoft.Shared.Diagnostics; namespace Microsoft.Extensions.Http.Resilience.Routing.Internal.WeightedGroups; internal sealed class WeightedGroupsRoutingStrategy : RequestRoutingStrategy { private readonly List<WeightedUriEndpointGroup> _groups; private readonly ObjectPool<WeightedGroupsRoutingStrategy> _pool; private bool _initialGroupPicked; private WeightedGroupSelectionMode _mode; private bool _initialized; public WeightedGroupsRoutingStrategy(Randomizer randomizer, ObjectPool<WeightedGroupsRoutingStrategy> pool) : base(randomizer) { _groups = []; _pool = pool; } public void Initialize(IEnumerable<WeightedUriEndpointGroup> groups, WeightedGroupSelectionMode mode) { _ = TryReset(); _initialized = true; _mode = mode; _groups.AddRange(groups); } public override void Dispose() => _pool.Return(this); public override bool TryReset() { _initialized = false; _mode = WeightedGroupSelectionMode.EveryAttempt; _groups.Clear(); _initialGroupPicked = false; return true; } public override bool TryGetNextRoute([NotNullWhen(true)] out Uri? nextRoute) { if (!_initialized) { Throw.InvalidOperationException("The routing strategy is not initialized."); } if (TryGetNextGroup(out var group)) { nextRoute = group!.Endpoints.SelectByWeight(e => e.Weight, Randomizer).Uri!; return true; } nextRoute = null; return false; } private bool TryGetNextGroup(out WeightedUriEndpointGroup? nextGroup) { if (_groups.Count == 0) { nextGroup = null; return false; } nextGroup = PickGroup(); _ = _groups.Remove(nextGroup); return true; } private WeightedUriEndpointGroup PickGroup() { if (!_initialGroupPicked) { _initialGroupPicked = true; return _groups.SelectByWeight(g => g.Weight, Randomizer); } if (_mode == WeightedGroupSelectionMode.InitialAttempt) { return _groups[0]; } else { return _groups.SelectByWeight(g => g.Weight, Randomizer); } } }