Можно ли поручить ServicePartitionClient взаимодействовать с конкретным узлом в сервисной матрице?

azure-service-fabric

358 просмотра

2 ответа

у меня есть

public class HttpCommunicationClient : HttpClient, ICommunicationClient
{
    public HttpCommunicationClient()
        : base(new HttpClientHandler() { AllowAutoRedirect = false, UseCookies = false })
    {
    }

    public HttpCommunicationClient(HttpMessageHandler handler)
        : base(handler)
    {
    }

    public HttpCommunicationClient(HttpMessageHandler handler, bool disposeHandler)
        : base(handler, disposeHandler)
    {
    }

    #region ICommunicationClient

    string ICommunicationClient.ListenerName { get; set; }

    ResolvedServiceEndpoint ICommunicationClient.Endpoint { get; set; }

    ResolvedServicePartition ICommunicationClient.ResolvedServicePartition { get; set; }

    #endregion ICommunicationClient
}

а также

public class HttpCommunicationClientFactory : CommunicationClientFactoryBase<HttpCommunicationClient>
{
    private readonly Func<HttpCommunicationClient> _innerDispatcherProvider;

    public HttpCommunicationClientFactory(IServicePartitionResolver servicePartitionResolver = null, IEnumerable<IExceptionHandler> exceptionHandlers = null, string traceId = null)
        : this(() => new HttpCommunicationClient(), servicePartitionResolver, exceptionHandlers, traceId)
    {
    }

    public HttpCommunicationClientFactory(Func<HttpCommunicationClient> innerDispatcherProvider, IServicePartitionResolver servicePartitionResolver = null, IEnumerable<IExceptionHandler> exceptionHandlers = null, string traceId = null)
        : base(servicePartitionResolver, exceptionHandlers, traceId)
    {
        if (innerDispatcherProvider == null)
        {
            throw new ArgumentNullException(nameof(innerDispatcherProvider));
        }

        _innerDispatcherProvider = innerDispatcherProvider;
    }

    protected override void AbortClient(HttpCommunicationClient dispatcher)
    {
        if (dispatcher != null)
        {
            dispatcher.Dispose();
        }
    }

    protected override Task<HttpCommunicationClient> CreateClientAsync(string endpoint, CancellationToken cancellationToken)
    {
        var dispatcher = _innerDispatcherProvider.Invoke();
        dispatcher.BaseAddress = new Uri(endpoint, UriKind.Absolute);

        return Task.FromResult(dispatcher);
    }

    protected override bool ValidateClient(HttpCommunicationClient dispatcher)
    {
        return dispatcher != null && dispatcher.BaseAddress != null;
    }

    protected override bool ValidateClient(string endpoint, HttpCommunicationClient dispatcher)
    {
        return dispatcher != null && dispatcher.BaseAddress == new Uri(endpoint, UriKind.Absolute);
    }
} 

и использует его, как показано ниже

var servicePartitionClient = new ServicePartitionClient<HttpCommunicationClient>(_httpClientFactory,
                                                                                           _options.ServiceUri,
                                                                                           _options.GetServicePartitionKey?.Invoke(context),
                                                                                           _options.TargetReplicaSelector,
                                                                                           _options.ListenerName,
                                                                                           _options.OperationRetrySettings);

using (var responseMessage = await servicePartitionClient.InvokeWithRetryAsync(httpClient => ExecuteServiceCallAsync(httpClient, context)))
{
    await responseMessage.CopyToCurrentContext(context);
}

Теперь возникает вопрос: если во время использования ServicePartitionClient я знаю, что я хотел бы подключиться к определенному узлу, есть ли способ сделать это?

Дело в том, что это приложение-шлюз, которое пересылает запросы другим службам, и я хотел бы, чтобы он вел себя как в случае слипающихся сеансов.

Автор: Poul K. Sørensen Источник Размещён: 08.11.2019 11:16

Ответы (2)


0 плюса

Решение

Более разумно думать с точки зрения сервисов, чем узлов. Таким образом, вместо того, чтобы подключаться к определенному узлу, вы фактически подключаетесь к определенному экземпляру службы.

Когда вы подключаетесь к службе, если она не имеет состояния, не должно иметь значения, к какому экземпляру вы подключаетесь, по определению, что она не имеет состояния. Если вы обнаружите, что пользователь привязан к определенному экземпляру службы, эта служба находится в состоянии с отслеживанием состояния (она отслеживает некоторое состояние пользователя), и это именно тот тип сценария, для которого предназначены службы с сохранением состояния .

Автор: Vaclav Turecek Размещён: 22.08.2016 07:48

0 плюса

Я нашел решение, в котором я в приведенном ExecuteServiceCallAsyncниже вызове считываю куки-файл из запроса с информацией о том, к какому узлу он был подключен, если это липкий сеанс, и, если нет куки-файла, я устанавливаю один с информацией из запроса. Если узел больше не существует, файл cookie обновляется до нового узла.

using (var responseMessage = await servicePartitionClient.InvokeWithRetryAsync(httpClient => ExecuteServiceCallAsync(httpClient, context)))
{
    await responseMessage.CopyToCurrentContext(context);
}
Автор: Poul K. Sørensen Размещён: 20.08.2016 12:22
Вопросы из категории :
32x32