Skip to content

Commit

Permalink
Add start and stop api to centralized service client (#53)
Browse files Browse the repository at this point in the history
* Add start and stop api to centralized service client and use it to manage the connection properly.

* Check service client existence and properly destroy the channel object.
  • Loading branch information
tusmester authored Nov 17, 2021
1 parent fb79874 commit 8209a3a
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 47 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace SenseNet.Search.Lucene29.Centralized.Common
namespace SenseNet.Search.Lucene29.Centralized.Common
{
public interface ISearchServiceClient : ISearchServiceContract
{
Expand All @@ -11,5 +7,14 @@ public interface ISearchServiceClient : ISearchServiceContract
/// </summary>
/// <returns>An <see cref="ISearchServiceClient"/> instance.</returns>
ISearchServiceClient CreateInstance();

/// <summary>
/// Starts the underlying client and opens the connection.
/// </summary>
void Start();
/// <summary>
/// Stops the underlying client and closes the connection.
/// </summary>
void ShutDown();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,21 +97,17 @@ public static IServiceCollection AddLucene29CentralizedSearchEngineWithGrpc(this
{
ServerCertificateCustomValidationCallback = (message, certificate2, arg3, arg4) => true
});
options.ChannelOptions.DisposeHttpClient = true;
// Do not set the DisposeHttpClient property to True because the client may be used
// multiple times when starting and stopping the service in a single app domain.
});

if (configure != null)
services.Configure(configure);

services
.AddLucene29CentralizedSearchEngine()
.AddLucene29CentralizedServiceClient(providers =>
{
var grpcOptions = providers.GetService<IOptions<GrpcClientOptions>>().Value;
grpcOptions.ChannelOptions.LoggerFactory = providers.GetService<ILoggerFactory>();
return CreateGrpcServiceClient(grpcOptions.ServiceAddress, grpcOptions.ChannelOptions);
});
.AddLucene29CentralizedServiceClient<GrpcServiceClient>();
return services;
}

Expand All @@ -126,6 +122,7 @@ internal static Search.Lucene29.Centralized.GrpcService.IndexingActivityStatus T
return request;
}

[Obsolete("Use dependency injection instead.")]
private static GrpcServiceClient CreateGrpcServiceClient(string serviceAddress, GrpcChannelOptions options)
{
// this channel will be disposed later, by the GrpcClientSnService class
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Grpc.Net.Client;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using SenseNet.Extensions.DependencyInjection;
using SenseNet.Search.Lucene29.Centralized.GrpcService;
Expand All @@ -31,26 +32,51 @@ public class GrpcServiceClient : ISearchServiceClient

/* =================================================== ISearchServiceContract */

private readonly GrpcSearchClient _searchClient;
private readonly GrpcChannel _channel;
private GrpcSearchClient _searchClient;
private GrpcChannel _channel;
private readonly ILogger<GrpcServiceClient> _logger;
private readonly GrpcClientOptions _options;

public GrpcServiceClient(IOptions<GrpcClientOptions> options, ILogger<GrpcServiceClient> logger)
{
_options = options.Value;
_logger = logger;
}

[Obsolete("Use the other constructor that is able to work with DI instead.")]
public GrpcServiceClient(GrpcSearchClient searchClient, GrpcChannel channel, GrpcChannelOptions options)
{
_options = new GrpcClientOptions
{
ChannelOptions = options,
ServiceAddress = channel.Target
};
_searchClient = searchClient;
_logger = options?.LoggerFactory?.CreateLogger<GrpcServiceClient>() ?? NullLogger<GrpcServiceClient>.Instance;

// we pin this object only to be able to shut it down properly later
_channel = channel;
}

public void Start()
{
_logger.LogInformation("Starting the Grpc channel...");

_channel = GrpcChannel.ForAddress(_options.ServiceAddress, _options.ChannelOptions);
_searchClient = new GrpcSearchClient(_channel);
}

public void ShutDown()
{
_logger.LogInformation("Shutting down the Grpc channel...");

// as the channel was created on app start, we need to
// dispose it properly when the connection is closed
_channel?.Dispose();
if (_channel != null)
{
_channel.Dispose();
_channel = null;
}
}

#region ISearchServiceContract implementation
Expand Down Expand Up @@ -166,7 +192,7 @@ public void SetIndexingInfo(IDictionary<string, IndexFieldAnalyzer> analyzerType
{
try
{
var request = new GrpcService.SetIndexingInfoRequest();
var request = new SetIndexingInfoRequest();

foreach (var (key, indexFieldAnalyzer) in analyzerTypes)
request.AnalyzerTypes.Add(key, (GrpcService.IndexFieldAnalyzer)indexFieldAnalyzer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.27.0" />
<PackageReference Include="SenseNet.Search" Version="2.4.8" />
<PackageReference Include="SenseNet.Security.EFCSecurityStore" Version="3.0.2" />
<PackageReference Include="SenseNet.Security.EFCSecurityStore" Version="3.0.3" />
<PackageReference Include="SenseNet.Security.Messaging.RabbitMQ" Version="1.2.1" />
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.Graylog" Version="2.2.2" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,12 @@ public Lucene29CentralizedIndexingEngine(ISearchServiceClient client, IOptions<C

public Task StartAsync(TextWriter consoleOut, CancellationToken cancellationToken)
{
// warmup
var unused = SearchServiceClient.Instance;
// start the underlying client
var client = SearchServiceClient.Instance;
if (client == null)
throw new InvalidOperationException("Service client is unavailable, service cannot be started.");

client.Start();

_running = true;
return Task.CompletedTask;
Expand All @@ -65,6 +69,10 @@ public Task ShutDownAsync(CancellationToken cancellationToken)
//TODO: we may write the indexing state (last activity id) to the index in the future
// to make the centralized index compatible with the local version. Currently the state
// is not written there because it is not needed for a centralized index to work.

SearchServiceClient.Instance?.ShutDown();
_running = false;

return Task.CompletedTask;
}

Expand Down
10 changes: 10 additions & 0 deletions src/SenseNet.Search.Lucene29.Centralized/SearchServiceClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,15 @@ public ISearchServiceClient CreateInstance()
{
return this;
}

public void Start()
{
// do nothing
}

public void ShutDown()
{
// do nothing
}
}
}
11 changes: 11 additions & 0 deletions src/SenseNet.Search.Lucene29.Centralized/WcfServiceClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,17 @@ public QueryResult<string> ExecuteQueryAndProject(SnQuery query, ServiceQueryCon
}

public ISearchServiceClient CreateInstance() => GetSearchServiceContract();

public void Start()
{
// do nothing
}

public void ShutDown()
{
// do nothing
}

#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ public ISearchServiceClient CreateInstance()
return this;
}

public void Start()
{
// do nothing
}

public void ShutDown()
{
// do nothing
}

public QueryResult<int> ExecuteQuery(SnQuery query, ServiceQueryContext queryContext)
{
using (var client = WcfServiceClient.GetSearchServiceContract())
Expand Down

0 comments on commit 8209a3a

Please sign in to comment.