forked from grpc/grpc-dotnet
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathTestResolver.cs
90 lines (77 loc) · 2.93 KB
/
TestResolver.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#region Copyright notice and license
// Copyright 2019 The gRPC Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#endregion
#if SUPPORT_LOAD_BALANCING
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Grpc.Core;
using Grpc.Net.Client.Balancer;
using Grpc.Net.Client.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
namespace Grpc.Tests.Shared;
internal class TestResolver : PollingResolver
{
private readonly object _lock;
private readonly Func<Task>? _onRefreshAsync;
private readonly TaskCompletionSource<object?> _hasResolvedTcs;
private readonly ILogger _logger;
private ResolverResult? _result;
public Task HasResolvedTask => _hasResolvedTcs.Task;
public TestResolver(ILoggerFactory loggerFactory) : this(loggerFactory, null)
{
}
public TestResolver(ILoggerFactory? loggerFactory = null, Func<Task>? onRefreshAsync = null) : base(loggerFactory ?? NullLoggerFactory.Instance)
{
_lock = new object();
_onRefreshAsync = onRefreshAsync;
_hasResolvedTcs = new TaskCompletionSource<object?>(TaskCreationOptions.RunContinuationsAsynchronously);
_logger = (ILogger?)loggerFactory?.CreateLogger<TestResolver>() ?? NullLogger.Instance;
}
public void UpdateAddresses(List<BalancerAddress> addresses, ServiceConfig? serviceConfig = null, Status? serviceConfigStatus = null)
{
_logger.LogInformation("Updating result addresses: {Addresses}", string.Join(", ", addresses));
UpdateResult(ResolverResult.ForResult(addresses, serviceConfig, serviceConfigStatus));
}
public void UpdateError(Status status)
{
_logger.LogInformation("Updating result error: {Status}", status);
UpdateResult(ResolverResult.ForFailure(status));
}
public void UpdateResult(ResolverResult result)
{
lock (_lock)
{
_result = result;
Listener?.Invoke(result);
}
}
protected override async Task ResolveAsync(CancellationToken cancellationToken)
{
if (_onRefreshAsync != null)
{
await _onRefreshAsync();
}
lock (_lock)
{
Listener(_result ?? ResolverResult.ForResult(Array.Empty<BalancerAddress>(), serviceConfig: null, serviceConfigStatus: null));
}
_hasResolvedTcs.TrySetResult(null);
}
}
#endif