public static void SendSubscriptionDocuments(TcpConnectionOptions tcpConnectionOptions) { var remoteEndPoint = tcpConnectionOptions.TcpClient.Client.RemoteEndPoint; Task.Run(async() => { using (tcpConnectionOptions) using (var connection = new SubscriptionConnection(tcpConnectionOptions)) using (tcpConnectionOptions.ConnectionProcessingInProgress("Subscription")) { try { bool gotSemaphore; if ((gotSemaphore = tcpConnectionOptions.DocumentDatabase.SubscriptionStorage.TryEnterSemaphore()) == false) { throw new SubscriptionClosedException( $"Cannot open new subscription connection, max amount of concurrent connections reached ({tcpConnectionOptions.DocumentDatabase.Configuration.Subscriptions.MaxNumberOfConcurrentConnections})"); } try { await connection.InitAsync(); await connection.ProcessSubscriptionAsync(); } finally { if (gotSemaphore) { tcpConnectionOptions.DocumentDatabase.SubscriptionStorage.ReleaseSubscriptionsSemaphore(); } } } catch (Exception e) { if (connection._logger.IsInfoEnabled) { connection._logger.Info( $"Failed to process subscription {connection.SubscriptionId} / from client {remoteEndPoint}", e); } try { await ReportExceptionToClient(connection, connection.ConnectionException ?? e); } catch (Exception) { // ignored } } finally { if (connection._logger.IsInfoEnabled) { connection._logger.Info( $"Finished processing subscription {connection.SubscriptionId} / from client {remoteEndPoint}"); } } } }); }
public SubscriptionConnection(TcpConnectionOptions connectionOptions) { TcpConnection = connectionOptions; ClientUri = connectionOptions.TcpClient.Client.RemoteEndPoint.ToString(); _logger = LoggingSource.Instance.GetLogger <SubscriptionConnection>(connectionOptions.DocumentDatabase.Name); CancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(TcpConnection.DocumentDatabase.DatabaseShutdown); _waitForMoreDocuments = new AsyncManualResetEvent(CancellationTokenSource.Token); Stats = new SubscriptionConnectionStats(); }
public SubscriptionConnection(TcpConnectionOptions connectionOptions) { TcpConnection = connectionOptions; _bufferedWriter = new BlittableJsonTextWriter(connectionOptions.Context, _buffer); _logger = LoggingSource.Instance.GetLogger <SubscriptionConnection>(connectionOptions.DocumentDatabase.Name); CancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(TcpConnection.DocumentDatabase.DatabaseShutdown); Stats = new SubscriptionConnectionStats(); TcpConnection.GetTypeSpecificStats = GetTypeSpecificStats; }
public SubscriptionConnection(TcpConnectionOptions connectionOptions, IDisposable tcpConnectionDisposable, JsonOperationContext.ManagedPinnedBuffer bufferToCopy) { TcpConnection = connectionOptions; _tcpConnectionDisposable = tcpConnectionDisposable; ClientUri = connectionOptions.TcpClient.Client.RemoteEndPoint.ToString(); _logger = LoggingSource.Instance.GetLogger <SubscriptionConnection>(connectionOptions.DocumentDatabase.Name); CancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(TcpConnection.DocumentDatabase.DatabaseShutdown); _waitForMoreDocuments = new AsyncManualResetEvent(CancellationTokenSource.Token); Stats = new SubscriptionConnectionStats(); _copiedBuffer = bufferToCopy.Clone(connectionOptions.ContextPool); }
public static void Run(TcpConnectionOptions tcpConnectionOptions) { var bulkInsertThread = new Thread(() => { var logger = LoggingSource.Instance.GetLogger <BulkInsertConnection>(tcpConnectionOptions.DocumentDatabase.Name); try { using (var bulkInsert = new BulkInsertConnection(tcpConnectionOptions, logger)) { bulkInsert.Execute(); } } catch (Exception e) { if (logger.IsInfoEnabled) { logger.Info("Failed to process bulk insert run", e); } try { using (var writer = new BlittableJsonTextWriter(tcpConnectionOptions.Context, tcpConnectionOptions.Stream)) { tcpConnectionOptions.Context.Write(writer, new DynamicJsonValue { ["Type"] = "Error", ["Exception"] = e.ToString() }); } } catch (Exception) { } } finally { tcpConnectionOptions.Dispose(); // Thread is going to die, let us release those resources early, instead of waiting for finalizer ByteStringMemoryCache.Clean(); tcpConnectionOptions.DocumentDatabase.DocumentsStorage.ContextPool.Clean(); } }) { IsBackground = true, Name = "Bulk Insert Operation" }; bulkInsertThread.Start(); }
public BulkInsertConnection(TcpConnectionOptions tcpConnection, Logger logger) { TcpConnection = tcpConnection; _logger = logger; }
public static void SendSubscriptionDocuments(TcpConnectionOptions tcpConnectionOptions) { Task.Run(async() => { var connection = new SubscriptionConnection(tcpConnectionOptions); tcpConnectionOptions.DisposeOnConnectionClose.Add(connection); try { if (await connection.InitAsync() == false) { return; } await connection.ProcessSubscriptionAysnc(); } catch (Exception e) { if (connection._logger.IsInfoEnabled) { connection._logger.Info($"Failed to process subscription {connection._options?.SubscriptionId} / from client {connection.TcpConnection.TcpClient.Client.RemoteEndPoint}", e); } try { if (connection.ConnectionException != null) { return; } using (var writer = new BlittableJsonTextWriter(tcpConnectionOptions.Context, tcpConnectionOptions.Stream)) { tcpConnectionOptions.Context.Write(writer, new DynamicJsonValue { ["Type"] = "Error", ["Exception"] = e.ToString() }); } } catch (Exception) { // ignored } } finally { if (connection._options != null && connection._logger.IsInfoEnabled) { connection._logger.Info($"Finished proccessing subscription {connection._options?.SubscriptionId} / from client {connection.TcpConnection.TcpClient.Client.RemoteEndPoint}"); } if (connection.ConnectionException != null) { try { var status = "None"; if (connection.ConnectionException is SubscriptionClosedException) { status = "Closed"; } using (var writer = new BlittableJsonTextWriter(tcpConnectionOptions.Context, tcpConnectionOptions.Stream)) { tcpConnectionOptions.Context.Write(writer, new DynamicJsonValue { ["Type"] = "Error", ["Status"] = status, ["Exception"] = connection.ConnectionException.ToString() }); } } catch { // ignored } } tcpConnectionOptions.Dispose(); } }); }