示例#1
0
 private void PrepareForNewDocumentParse(BlittableJsonDocumentBuilder.UsageMode mode, string debugTag)
 {
     _parser.NewDocument();
     _writer.Renew(debugTag, mode);
     _writer.ReadObjectDocument();
     _context.CachedProperties.NewDocument();
 }
        private async Task ListenForCommands()
        {
            await _clusterDashboardNotifications.EnsureWatcher(); // in current impl cluster dashboard senders talk to a single watcher

            using (_readContext.GetMemoryBuffer(out JsonOperationContext.MemoryBuffer segment1))
                using (_readContext.GetMemoryBuffer(out JsonOperationContext.MemoryBuffer segment2))
                {
                    try
                    {
                        var segments        = new[] { segment1, segment2 };
                        int index           = 0;
                        var receiveAsync    = _webSocket.ReceiveAsync(segments[index].Memory.Memory, _resourceShutdown);
                        var jsonParserState = new JsonParserState();
                        using (var parser = new UnmanagedJsonParser(_readContext, jsonParserState, "cluster-dashboard"))
                        {
                            var result = await receiveAsync;
                            _resourceShutdown.ThrowIfCancellationRequested();

                            parser.SetBuffer(segments[index], 0, result.Count);
                            index++;
                            receiveAsync = _webSocket.ReceiveAsync(segments[index].Memory.Memory, _resourceShutdown);

                            while (true)
                            {
                                using (var builder = new BlittableJsonDocumentBuilder(_readContext, BlittableJsonDocumentBuilder.UsageMode.None,
                                                                                      "cluster-dashboard", parser, jsonParserState))
                                {
                                    parser.NewDocument();
                                    builder.ReadObjectDocument();

                                    while (builder.Read() == false)
                                    {
                                        result = await receiveAsync;
                                        _resourceShutdown.ThrowIfCancellationRequested();

                                        parser.SetBuffer(segments[index], 0, result.Count);
                                        if (++index >= segments.Length)
                                        {
                                            index = 0;
                                        }

                                        receiveAsync = _webSocket.ReceiveAsync(segments[index].Memory.Memory, _resourceShutdown);
                                    }

                                    builder.FinalizeDocument();

                                    using (var reader = builder.CreateReader())
                                    {
                                        await HandleCommand(reader);
                                    }
                                }
                            }
                        }
                    }
                    catch (IOException ex)
                    {
                        /* Client was disconnected, write to log */
                        if (Logger.IsInfoEnabled)
                        {
                            Logger.Info("Client was disconnected", ex);
                        }
                    }
                    catch (Exception ex)
                    {
                        // if we received close from the client, we want to ignore it and close the websocket (dispose does it)
                        if (ex is WebSocketException webSocketException &&
                            webSocketException.WebSocketErrorCode == WebSocketError.InvalidState &&
                            _webSocket.State == WebSocketState.CloseReceived)
                        {
                            // ignore
                        }
示例#3
0
        private async Task HandleConnection(WebSocket webSocket, JsonOperationContext context)
        {
            // this flag can be used to detect if server was restarted between changes connections on client side
            var sendStartTime      = GetBoolValueQueryString("sendServerStartTime", false).GetValueOrDefault(false);
            var throttleConnection = GetBoolValueQueryString("throttleConnection", false).GetValueOrDefault(false);

            var connection = new NotificationsClientConnection(webSocket, Database);

            Database.Notifications.Connect(connection);
            var sendTask = connection.StartSendingNotifications(sendStartTime, throttleConnection);
            var debugTag = "changes/" + connection.Id;

            JsonOperationContext.ManagedPinnedBuffer segment1, segment2;
            using (context.GetManagedBuffer(out segment1))
                using (context.GetManagedBuffer(out segment2))
                {
                    try
                    {
                        var segments        = new[] { segment1, segment2 };
                        int index           = 0;
                        var receiveAsync    = webSocket.ReceiveAsync(segments[index].Buffer, Database.DatabaseShutdown);
                        var jsonParserState = new JsonParserState();
                        using (var parser = new UnmanagedJsonParser(context, jsonParserState, debugTag))
                        {
                            var result = await receiveAsync;
                            parser.SetBuffer(segments[index], result.Count);
                            index++;
                            receiveAsync = webSocket.ReceiveAsync(segments[index].Buffer, Database.DatabaseShutdown);

                            while (true)
                            {
                                using (var builder = new BlittableJsonDocumentBuilder(context, BlittableJsonDocumentBuilder.UsageMode.None, debugTag, parser, jsonParserState))
                                {
                                    parser.NewDocument();
                                    builder.ReadObjectDocument();

                                    while (builder.Read() == false)
                                    {
                                        result = await receiveAsync;

                                        parser.SetBuffer(segments[index], result.Count);
                                        if (++index >= segments.Length)
                                        {
                                            index = 0;
                                        }
                                        receiveAsync = webSocket.ReceiveAsync(segments[index].Buffer, Database.DatabaseShutdown);
                                    }

                                    builder.FinalizeDocument();

                                    using (var reader = builder.CreateReader())
                                    {
                                        string command, commandParameter;
                                        if (reader.TryGet("Command", out command) == false)
                                        {
                                            throw new ArgumentNullException(nameof(command), "Command argument is mandatory");
                                        }

                                        reader.TryGet("Param", out commandParameter);
                                        connection.HandleCommand(command, commandParameter);

                                        int commandId;
                                        if (reader.TryGet("CommandId", out commandId))
                                        {
                                            connection.Confirm(commandId);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (IOException ex)
                    {
                        /* Client was disconnected, write to log */
                        if (Logger.IsInfoEnabled)
                        {
                            Logger.Info("Client was disconnected", ex);
                        }
                    }
                    finally
                    {
                        Database.Notifications.Disconnect(connection.Id);
                    }
                }
            await sendTask;
        }
示例#4
0
        private async Task HandleConnection(WebSocket webSocket, JsonOperationContext context)
        {
            var fromStudio         = GetBoolValueQueryString(StudioMarker, false) ?? false;
            var throttleConnection = GetBoolValueQueryString("throttleConnection", false).GetValueOrDefault(false);

            var connection = new ChangesClientConnection(webSocket, Database, fromStudio);

            Database.Changes.Connect(connection);
            var sendTask = connection.StartSendingNotifications(throttleConnection);
            var debugTag = "changes/" + connection.Id;

            using (context.GetManagedBuffer(out JsonOperationContext.ManagedPinnedBuffer segment1))
                using (context.GetManagedBuffer(out JsonOperationContext.ManagedPinnedBuffer segment2))
                {
                    try
                    {
                        var segments        = new[] { segment1, segment2 };
                        int index           = 0;
                        var receiveAsync    = webSocket.ReceiveAsync(segments[index].Buffer, Database.DatabaseShutdown);
                        var jsonParserState = new JsonParserState();
                        using (var parser = new UnmanagedJsonParser(context, jsonParserState, debugTag))
                        {
                            var result = await receiveAsync;
                            Database.DatabaseShutdown.ThrowIfCancellationRequested();

                            parser.SetBuffer(segments[index], 0, result.Count);
                            index++;
                            receiveAsync = webSocket.ReceiveAsync(segments[index].Buffer, Database.DatabaseShutdown);

                            while (true)
                            {
                                using (var builder =
                                           new BlittableJsonDocumentBuilder(context, BlittableJsonDocumentBuilder.UsageMode.None, debugTag, parser, jsonParserState))
                                {
                                    parser.NewDocument();
                                    builder.ReadObjectDocument();

                                    while (builder.Read() == false)
                                    {
                                        result = await receiveAsync;
                                        Database.DatabaseShutdown.ThrowIfCancellationRequested();

                                        parser.SetBuffer(segments[index], 0, result.Count);
                                        if (++index >= segments.Length)
                                        {
                                            index = 0;
                                        }
                                        receiveAsync = webSocket.ReceiveAsync(segments[index].Buffer, Database.DatabaseShutdown);
                                    }

                                    builder.FinalizeDocument();

                                    using (var reader = builder.CreateReader())
                                    {
                                        if (reader.TryGet("Command", out string command) == false)
                                        {
                                            throw new ArgumentNullException(nameof(command), "Command argument is mandatory");
                                        }

                                        reader.TryGet("Param", out string commandParameter);
                                        reader.TryGet("Params", out BlittableJsonReaderArray commandParameters);

                                        connection.HandleCommand(command, commandParameter, commandParameters);

                                        if (reader.TryGet("CommandId", out int commandId))
                                        {
                                            connection.Confirm(commandId);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (IOException ex)
                    {
                        /* Client was disconnected, write to log */
                        if (Logger.IsInfoEnabled)
                        {
                            Logger.Info("Client was disconnected", ex);
                        }
                    }
                    catch
                    {
#pragma warning disable 4014
                        sendTask.IgnoreUnobservedExceptions();
#pragma warning restore 4014

                        throw;
                    }
                    finally
                    {
                        Database.Changes.Disconnect(connection.Id);
                    }
                }
            await sendTask;
        }