MailKit version 2.15.0 disconnection issue - mailkit

I am using MailKit version 2.15.0. When trying to disconnect the client using DisconnectAsync, I am getting the below error
ClientDisconnect method()==> Exception Message: The ReadAsync method cannot be called when another read operation is pending., Exception String: System.NotSupportedException: The ReadAsync method cannot be called when another read operation is pending.
at System.Net.Security.SslStream.ReadAsyncInternal[TIOAdapter](TIOAdapter adapter, Memory`1 buffer)
at MailKit.Net.Pop3.Pop3Stream.ReadAheadAsync(Boolean doAsync, CancellationToken cancellationToken)
at MailKit.Net.Pop3.Pop3Stream.ReadLineAsync(Stream ostream, Boolean doAsync, CancellationToken cancellationToken)
at MailKit.Net.Pop3.Pop3Engine.ReadLineAsync(Boolean doAsync, CancellationToken cancellationToken)
at MailKit.Net.Pop3.Pop3Engine.ReadResponseAsync(Pop3Command pc, Boolean doAsync)
at MailKit.Net.Pop3.Pop3Engine.IterateAsync(Boolean doAsync)
at MailKit.Net.Pop3.Pop3Client.SendCommandAsync(Boolean doAsync, CancellationToken token, String command)
at MailKit.Net.Pop3.Pop3Client.DisconnectAsync(Boolean quit, Boolean doAsync, CancellationToken cancellationToken)
Below is the code I am using to Disconnect the Client
private async Task DisconnectClient(Hashtable markAsRead, EmailServer emailServer)
{
pollingInProgress = false;
await emailServer.ClientDisconnect(markAsRead);
markAsRead.Clear();
}
internal void MarkAsRead(Hashtable markAsRead)
{
emailBinding.emailSource().MarkRead(markAsRead);
}
internal async Task ClientDisconnect(Hashtable markAsRead)
{
try
{
if (!emailBinding.emailSource().IsConnected)
{
await emailBinding.Connect();
}
FlushClient(markAsRead);
await emailBinding.Disconnect();
}
catch (Exception e)
{
AttachWorkerLogs(string.Format("ClientDisconnect method()==> Exception Message: {0}, Exception String: {1}", e.Message, e.ToString()));
throw;
}
}
private void FlushClient(Hashtable markAsRead)
{
MarkAsRead(markAsRead);
}
Finally calling the disconnect method like this:
public async Task Disconnect()
{
try
{
if (client.IsConnected)
{
await client.DisconnectAsync(true);
}
}
catch (Exception e)
{
AttachLogger(string.Format("Disconnect method()==> Exception Message: {0}, Exception String: {1}", e.Message, e.ToString()));
throw;
}
}
I am unable to figure out what exactly is the issue.

The exception message makes it pretty clear that you are trying to read from the SslStream from multiple threads at the same time.
Since MailKit is not multi-threaded, it means that you are effectively trying to perform 2 or more operations on the same Pop3Client from multiple threads at the same time.
In other words, the problem is not that you are calling Disconnect, the problem is that you are calling Disconnect when your code is also trying to download messages or something from the server.

Related

getting 500 error by calling any route which is getting data from database in azure-web-app-service

recently i have deployed my .net 5.0 api in azure web app without azure database. The app is running fine but i am not able to call any route which is getting data from my postgresql database. The api and getting data from my database is working fine in my local pc, but when i call any route in azure web app i get 500 internal server error and the detail error look like this.
error #1
Category: Microsoft.EntityFrameworkCore.Database.Connection
EventId: 20004
SpanId: 81307fd2722df04f
TraceId: 17283bbac7e9c74ab0dea8dafdf0a12a
ParentId: 0000000000000000
ConnectionId: 0HMB63E788EM6
RequestId: 0HMB63E788EM6:00000004
RequestPath: /api/someList
ActionId: d26cb19d-75cd-4847-828f-a74e2b5324ee
ActionName: QuranApi.Controllers.QuranTextController.GetSomeList (MyApi)
An error occurred using the connection to database 'MyDatabase' on server
'tcp://localhost:5432'.
error #2
Category: Microsoft.EntityFrameworkCore.Query
EventId: 10100
SpanId: 81307fd2722df04f
TraceId: 17283bbac7e9c74ab0dea8dafdf0a12a
ParentId: 0000000000000000
ConnectionId: 0HMB63E788EM6
RequestId: 0HMB63E788EM6:00000004
RequestPath: /api/someList
ActionId: d26cb19d-75cd-4847-828f-a74e2b5324ee
ActionName: QuranApi.Controllers.QuranTextController.GetSomeList (MyApi)
An exception occurred while iterating over the results of a query for context type
'QuranApi.PostgreSqlContext'.
System.InvalidOperationException: An exception has been raised that is likely due to
a transient failure.
---> Npgsql.NpgsqlException (0x80004005): Exception while connecting
---> System.Net.Sockets.SocketException (10013): An attempt was made to access a
socket in a way forbidden by its access permissions.
at Npgsql.NpgsqlConnector.Connect(NpgsqlTimeout timeout)
at Npgsql.NpgsqlConnector.Connect(NpgsqlTimeout timeout)
at Npgsql.NpgsqlConnector.RawOpen(NpgsqlTimeout timeout, Boolean async,
CancellationToken cancellationToken)
at Npgsql.NpgsqlConnector.Open(NpgsqlTimeout timeout, Boolean async,
CancellationToken cancellationToken)
at Npgsql.ConnectorPool.OpenNewConnector(NpgsqlConnection conn, NpgsqlTimeout
timeout, Boolean async, CancellationToken cancellationToken)
at Npgsql.ConnectorPool.<>c__DisplayClass38_0.<<Rent>g__RentAsync|0>d.MoveNext()
--- End of stack trace from previous location ---
at Npgsql.NpgsqlConnection.<>c__DisplayClass41_0.<<Open>g__OpenAsync|0>d.MoveNext()
--- End of stack trace from previous location ---
at Npgsql.NpgsqlConnection.Open()
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.
OpenDbConnection(Boolean errorsExpected)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternal(Boolean
errorsExpected)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean
errorsExpected)
at
Microsoft.EntityFrameworkCore.Storage.RelationalCommand.
ExecuteReader(RelationalCommandParameterObject parameterObject)at
Microsoft.EntityFrameworkCore.Query.Internal.
SingleQueryingEnumerable`1.Enumerator.
InitializeReader(DbContext _, Boolean result)at
Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.
NpgsqlExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation,
Func`3 verifySucceeded)
--- End of inner exception stack trace ---
at
Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.
NpgsqlExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation,
Func`3 verifySucceeded)at Microsoft.EntityFrameworkCore.Query.Internal.
SingleQueryingEnumerable`1.Enumerator.MoveNext()
Exception:
System.InvalidOperationException: An exception has been raised that is likely due to
a transient failure.
---> Npgsql.NpgsqlException (0x80004005): Exception while connecting
---> System.Net.Sockets.SocketException (10013): An attempt was made to access a
socket in a way forbidden by its access permissions.
at Npgsql.NpgsqlConnector.Connect(NpgsqlTimeout timeout)
at Npgsql.NpgsqlConnector.Connect(NpgsqlTimeout timeout)
at Npgsql.NpgsqlConnector.RawOpen(NpgsqlTimeout timeout, Boolean async,
CancellationToken cancellationToken)
at Npgsql.NpgsqlConnector.Open(NpgsqlTimeout timeout, Boolean async,
CancellationToken cancellationToken)
at Npgsql.ConnectorPool.OpenNewConnector(NpgsqlConnection conn, NpgsqlTimeout
timeout, Boolean async, CancellationToken cancellationToken)
at Npgsql.ConnectorPool.<>c__DisplayClass38_0.<<Rent>g__RentAsync|0>d.MoveNext()
--- End of stack trace from previous location ---
at Npgsql.NpgsqlConnection.<>c__DisplayClass41_0.<<Open>g__OpenAsync|0>d.MoveNext()
--- End of stack trace from previous location ---
at Npgsql.NpgsqlConnection.Open()at
Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnection(Boolean
errorsExpected)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternal(Boolean
errorsExpected)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean
errorsExpected) at
Microsoft.EntityFrameworkCore.Storage.RelationalCommand.
ExecuteReader(RelationalCommandParameterObject parameterObject)
at
Microsoft.EntityFrameworkCore.Query.Internal.
SingleQueryingEnumerable`1.Enumerator.InitializeReader(DbContext _, Boolean result)
at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.
Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
--- End of inner exception stack trace ---
at
Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.
Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at
Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.
Enumerator.MoveNext()
error #3
Category: Microsoft.AspNetCore.Server.Kestrel
EventId: 13
SpanId: 81307fd2722df04f
TraceId: 17283bbac7e9c74ab0dea8dafdf0a12a
ParentId: 0000000000000000
ConnectionId: 0HMB63E788EM6
RequestId: 0HMB63E788EM6:00000004
RequestPath: /api/someList
Connection id "0HMB63E788EM6", Request id "0HMB63E788EM6:00000004": An unhandled
exception was thrown by the application.
Exception:
System.InvalidOperationException: An exception has been raised that is likely due to
a transient failure.
---> Npgsql.NpgsqlException (0x80004005): Exception while connecting
---> System.Net.Sockets.SocketException (10013): An attempt was made to access a
socket in a way forbidden by its access permissions.
my Program.cs File
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseUrls("https://localhost:5000", "https://IP-Address-of-my-PC")
.UseIISIntegration()
.UseStartup<Startup>();
});
}
And my Startup.cs File
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
var sqlConnectionString = Configuration["ConnectionString"];
services.AddDbContext<PostgreSqlContext>(options =>
options.UseNpgsql(connectionString: sqlConnectionString));
services.AddScoped<IDataAccessProvider, DataAccessProvider>();
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1",
new OpenApiInfo
{
Title = "MyApi",
Version = "v1"
});
});
}
// This method gets called by the runtime.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseSwagger();
app.UseSwaggerUI(options =>
options.SwaggerEndpoint("/swagger/v1/swagger.json", "MyApi v1"));
}
}
i would be very happy if anybody can help me with this. I dont know what to do.

Reply Kafka Template - Exception handling

I am using ReplyingKafkaTemplate to establish a synchronous call between two microservices.
The receiver of the event is annotated with SendTo as below:
#KafkaListener(topics = "${kafka.topic.prefix}"
+ "${kafka.topic.name}", containerFactory = "customEventKafkaListenerFactory")
#SendTo
public CustomResponseEvent onMessage(
#Payload #Valid CustomRequestEvent event, #Header(KafkaHeaders.CORRELATION_ID) String correlationId,
#Header(KafkaHeaders.REPLY_TOPIC) String replyTopic) {
//Making some REST API calls to another external system here using RestTemplate
}
The REST API call can throw a 4xx or 5xx. There are multiple such calls, some to internal systems, and some to external systems. It may be a bad design, but let's not get into that.
I would like to have a global exception handler for the RestTemplate where I can catch all the exceptions, and then return a response to the original sender of the event.
I am using the same replyTopic and correlationId as received in the consumer to publish the event.
But still the receiver of the response throws No pending reply exception.
Whatever approach I have above, is it possible to achieve such a central error response event publisher?
Is there any other alternative that is best suited for this exception handling?
The #KafkaListener comes with the:
/**
* Set an {#link org.springframework.kafka.listener.KafkaListenerErrorHandler} bean
* name to invoke if the listener method throws an exception.
* #return the error handler.
* #since 1.3
*/
String errorHandler() default "";
That one is used to catch and process all the downstream exceptions and if it returns a result, it is sent back to the replyTopic:
public void onMessage(ConsumerRecord<K, V> record, Acknowledgment acknowledgment, Consumer<?, ?> consumer) {
Message<?> message = toMessagingMessage(record, acknowledgment, consumer);
logger.debug(() -> "Processing [" + message + "]");
try {
Object result = invokeHandler(record, acknowledgment, message, consumer);
if (result != null) {
handleResult(result, record, message);
}
}
catch (ListenerExecutionFailedException e) { // NOSONAR ex flow control
if (this.errorHandler != null) {
try {
Object result = this.errorHandler.handleError(message, e, consumer);
if (result != null) {
handleResult(result, record, message);
}
}
catch (Exception ex) {
throw new ListenerExecutionFailedException(createMessagingErrorMessage(// NOSONAR stack trace loss
"Listener error handler threw an exception for the incoming message",
message.getPayload()), ex);
}
}
else {
throw e;
}
}
See RecordMessagingMessageListenerAdapter source code for more info.

A connection attempt failed error when accessing MongoDB under load test

We're beginning to leverage MongoDB for search functionality in our application, to improve performance over how we used to do searches with SQL Server. Individual testing works fine, however now we've begun load testing with 40 concurrent "users" executing searches against MongoDB at once. Part way through each load test, many of the calls start erroring:
MongoDB.Driver.MongoConnectionException: An exception occurred while receiving a message from the server. ---> System.IO.IOException: Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
--- End of inner exception stack trace ---
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at MongoDB.Driver.Core.Misc.StreamExtensionMethods.ReadBytes(Stream stream, Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
at MongoDB.Driver.Core.Connections.BinaryConnection.ReceiveBuffer()
--- End of inner exception stack trace ---
at MongoDB.Driver.Core.Connections.BinaryConnection.ReceiveBuffer()
at MongoDB.Driver.Core.Connections.BinaryConnection.ReceiveBuffer(Int32 responseTo, CancellationToken cancellationToken)
at MongoDB.Driver.Core.Connections.BinaryConnection.ReceiveMessage(Int32 responseTo, IMessageEncoderSelector encoderSelector, MessageEncoderSettings messageEncoderSettings, CancellationToken cancellationToken)
at MongoDB.Driver.Core.ConnectionPools.ExclusiveConnectionPool.AcquiredConnection.ReceiveMessage(Int32 responseTo, IMessageEncoderSelector encoderSelector, MessageEncoderSettings messageEncoderSettings, CancellationToken cancellationToken)
at MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1.Execute(IConnection connection, CancellationToken cancellationToken)
at MongoDB.Driver.Core.WireProtocol.CommandWireProtocol`1.Execute(IConnection connection, CancellationToken cancellationToken)
at MongoDB.Driver.Core.Servers.Server.ServerChannel.ExecuteProtocol[TResult](IWireProtocol`1 protocol, CancellationToken cancellationToken)
at MongoDB.Driver.Core.Servers.Server.ServerChannel.Command[TResult](ICoreSession session, ReadPreference readPreference, DatabaseNamespace databaseNamespace, BsonDocument command, IEnumerable`1 commandPayloads, IElementNameValidator commandValidator, BsonDocument additionalOptions, Action`1 postWriteAction, CommandResponseHandling responseHandling, IBsonSerializer`1 resultSerializer, MessageEncoderSettings messageEncoderSettings, CancellationToken cancellationToken)
at MongoDB.Driver.Core.Operations.CommandOperationBase`1.ExecuteProtocol(IChannelHandle channel, ICoreSessionHandle session, ReadPreference readPreference, CancellationToken cancellationToken)
at MongoDB.Driver.Core.Operations.CommandOperationBase`1.ExecuteProtocol(IChannelSource channelSource, ICoreSessionHandle session, ReadPreference readPreference, CancellationToken cancellationToken)
at MongoDB.Driver.Core.Operations.ReadCommandOperation`1.Execute(IReadBinding binding, CancellationToken cancellationToken)
at MongoDB.Driver.Core.Operations.AggregateOperation`1.Execute(IReadBinding binding, CancellationToken cancellationToken)
at MongoDB.Driver.OperationExecutor.ExecuteReadOperation[TResult](IReadBinding binding, IReadOperation`1 operation, CancellationToken cancellationToken)
at MongoDB.Driver.MongoCollectionImpl`1.ExecuteReadOperation[TResult](IClientSessionHandle session, IReadOperation`1 operation, ReadPreference readPreference, CancellationToken cancellationToken)
at MongoDB.Driver.MongoCollectionImpl`1.ExecuteReadOperation[TResult](IClientSessionHandle session, IReadOperation`1 operation, CancellationToken cancellationToken)
at MongoDB.Driver.MongoCollectionImpl`1.Aggregate[TResult](IClientSessionHandle session, PipelineDefinition`2 pipeline, AggregateOptions options, CancellationToken cancellationToken)
at MongoDB.Driver.MongoCollectionImpl`1.<>c__DisplayClass19_0`1.<Aggregate>b__0(IClientSessionHandle session)
at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSession[TResult](Func`2 func, CancellationToken cancellationToken)
at MongoDB.Driver.MongoCollectionImpl`1.Aggregate[TResult](PipelineDefinition`2 pipeline, AggregateOptions options, CancellationToken cancellationToken)
at RealtorsPropertyResource.Rpr.MongoSearches.Model.QueryPropertiesForKeys[T](PerformanceMonitor performanceMonitor, PropertiesSearchCriteria criteria, RequiredDataResult requiredData)
at RealtorsPropertyResource.Rpr.MongoSearches.Model.SearchWithMongo(PropertiesSearchCriteria criteria, PerformanceMonitor performanceMonitor)
at RealtorsPropertyResource.Rpr.MongoSearches.Model.SearchForProperties(PropertiesSearchCriteria criteria, PerformanceMonitor performanceMonitor, Nullable`1 useMongo)
at RealtorsPropertyResource.Rpr.Websites.Main.AjaxService.ExecuteLoadTestSearch(AppPropertyMode appPropertyMode, SearchType searchType, String query) in C:\BuildAgents\RPR-Website\_work\4\s\Websites\Main\services\AjaxService.Search.cs:line 260
at SyncInvokeExecuteLoadTestSearch(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
We tested against two Mongo instances, one running on Windows and one running on Linux, and both are hitting this error. The searches that are completing successfully aren't slow, so I'm not confident this is a timeout issue, but perhaps maybe a max connection issue? I'm confused though because I thought the default connection limit for the MongoDB C# driver was 100 connections, and that limit for the MongoDB server itself was much higher than that.
Any suggestions of how to troubleshoot this error that only occurs while Mongo is under load?
In case it's relevant, here is how I'm instantiating a singleton MongoClient and IMongoDatabase:
public static class MongoContext
{
private static bool initialized = false;
private static string connectionString { get; set; }
private static IMongoDatabase database;
public static IMongoDatabase Database
{
get
{
if (database == null)
throw new InvalidOperationException("You must initialize the MongoContext first");
return database;
}
}
public static void Initialize()
{
if (!initialized)
{
initialized = true;
connectionString = RprConfigurationManager.GetConnectionString("MongoSearch");
Console.WriteLine("Connecting to MongoDB search database: " + connectionString);
var useSsl = connectionString.IndexOf("ssl=true", StringComparison.InvariantCultureIgnoreCase) >= 0;
var url = new MongoUrl(connectionString);
var clientSettings = MongoClientSettings.FromUrl(url);
clientSettings.SslSettings = new SslSettings();
clientSettings.SslSettings.CheckCertificateRevocation = false;
clientSettings.UseSsl = useSsl;
clientSettings.VerifySslCertificate = false;
var client = new MongoClient(clientSettings);
var lastSegment = connectionString.Split('/').Last();
var databaseSegments = lastSegment.Split('?');
var databaseName = databaseSegments.First();
databaseName = !String.IsNullOrEmpty(databaseName) ? databaseName : "rpr";
Console.WriteLine("Connecting to database: " + databaseName);
database = client.GetDatabase(databaseName);
SchemaInitializer.RegisterClassMaps();
}
}
}
Here are some mongod logs, in case it helps:
IXSCAN { CityPlaceId: 1, ForSaleGroupId: 1, DistressedGroupId: 1,
OffMarketGroupId: 1, ForLeaseGroupId: 1, ForSaleDistressedGroupId: 1,
OffMarketDistressedGroupId: 1, OrgId: 1, OrgSecurableId: 1,
OffMarketDate: 1, IsListingOnly: 1 } keysExamined:397707
docsExamined:332738 hasSortStage:1 cursorExhausted:1 numYields:20750
nreturned:1 reslen:1454 locks:{ Global: { acquireCount: { r: 21121 }
}, Database: { acquireCount: { r: 21121 } }, Collection: {
acquireCount: { r: 21121 } } } storage:{ data: { bytesRead:
7534883557, timeReadingMicros: 325960940 } } protocol:op_msg 356835ms
2019-08-19T19:43:08.856+0000 I NETWORK [conn285] Error sending
response to client: SocketException: An established connection was
aborted by the software in your host machine.. Ending connection from
172.27.129.209:65121 (connection id: 285) 2019-08-19T19:43:08.856+0000 I NETWORK [conn285] end connection 172.27.129.209:65121 (30
connections now open)
Here is mentioned that can be a problem with the driver, In our case we change the driver version from 2.5 to 2.10 and worked.

TryReceive method on IMessageReceiver interface

Please provide the following methods in IMessageReceiver:
bool TryReceive(out Message msg, TimeSpan timeout)
Task<bool> TryReceiveAsync(out Message msg, TimeSpan timeout)
So that we can use these like:
if (TryReceive(out Message msg, TimeSpan.FromSeconds(30))
{
...
}
else
{
...
}
If you want to make a feature request for Azure Functions you can leave that feedback here: https://feedback.azure.com/forums/355860-azure-functions

ConnectionPoolTimeoutException: timeout waiting for connection from pool

I have app that keep calling an api for json data, and pretty quickly i saw this 'Timeout waiting for connection from pool' exception, I googled around and found that's a connection leak caused by content not consumed, so i updated the code to close the inputstream after consume the jsondata, but still got those connection timeout exception, here is my code:
InputStream is = ApiUtil.getAsStream(Api.get(bookUrl).param("limit","500").param("bookId", bid).enable(Options.LongRunning), 3);
List<JsonBook> books = mapper.readValue(is, BOOK_TYPE);
is.close()
Api:
private JsonHttpClient client;
public APIForGet get(String endpoint) {
return new APIForGet(this.client, endpoint);
}
ApiUtil:
public static InputStream getAsStream(APIForGet get, Iterable<Long>retries) {
return get.asStream();
}
APIForGet:
private JsonHttpClient client;
public InputStream asStream() {
return this.client.getAsStream(this.hostname, this.port, this.endpoint, params, optionsArray());
}
JsonHttpClientImpl:
public InputStream getAsStream(Optional<String> host, Optional<Integer> port,String path, Multimap<String, String> param, Options ... options) {
HttpResponse reponse;
try {
response = request.execute();
if (response.isSuccessStatusCode()) {
return response.getContent();
}
} catch (Exception e) {
throw new Exception();
}
}
the wrapping logic here is kind of complicated, but eventually i think by closing the inputstream should work, any thoughts? Thanks!
try {
response = request.execute();
if (response.isSuccessStatusCode()) {
return response.getContent();
}
} catch (Exception e) {
throw new Exception();
}finally{
//TODO release conn or abort
}