예제 #1
0
        public async Task <BlittableJsonReaderObject> TryReadFromWebSocket(
            JsonOperationContext context,
            RavenClientWebSocket webSocket,
            string debugTag,
            CancellationToken cancellationToken)
        {
            var jsonParserState = new JsonParserState();

            JsonOperationContext.ManagedPinnedBuffer bytes;
            using (context.GetManagedBuffer(out bytes))
                using (var parser = new UnmanagedJsonParser(context, jsonParserState, debugTag))
                {
                    var writer = new BlittableJsonDocumentBuilder(context,
                                                                  BlittableJsonDocumentBuilder.UsageMode.None, debugTag, parser, jsonParserState);

                    writer.ReadObjectDocument();

                    var result = await webSocket.ReceiveAsync(bytes.Buffer, cancellationToken).ConfigureAwait(false);

                    parser.SetBuffer(bytes, result.Count);
                    while (writer.Read() == false)
                    {
                        // we got incomplete json response.
                        // This might happen if we close the connection but still server sends something
                        if (result.CloseStatus != null)
                        {
                            return(null);
                        }

                        result = await webSocket.ReceiveAsync(bytes.Buffer, cancellationToken).ConfigureAwait(false);

                        parser.SetBuffer(bytes, result.Count);
                    }
                    writer.FinalizeDocument();
                    return(writer.CreateReader());
                }
        }
예제 #2
0
 public unsafe void Valid_String()
 {
     using (var ctx = JsonOperationContext.ShortTermSingleUse())
     {
         var state = new JsonParserState();
         using (var parser = new UnmanagedJsonParser(ctx, state, "test"))
         {
             var temp = new Str
             {
                 str = "\nabcdefghijklmnopqrstuvwxyz" +
                       "abcdefghijklmnopqrstuvwxyz" +
                       "abcdefghijklmnopqrstuvwxyz" +
                       "abcdefghijklmnopqrstuvwxyz" +
                       "abcdefghijklmnopqrstuvwxyz" +
                       "abcdefghijklmnopqrstuvwxyz" +
                       "abcdefghijklmnopqrstuvwxyz" +
                       "abcdefghijklmnopqrstuvwxyz" +
                       "abcdefghijklmnopqrstuvwxyz" +
                       "abcdefghijklmnopqrstuvwxyz" +
                       "abcdefghijklmnopqrstuvwxyz" +
                       "abcdefghijklmnopqrstuvwxyz" +
                       "abcdefghijklmnopqrstuvwxyz" +
                       "abcdefghijklmnopqrstuvwxyz" +
                       "abcdefghijklmnopqrstuvwxyz" +
                       "abcdefghijklmnopqrstuvwxyz" +
                       "abcdefghijklmnopqrstuvwxyz" +
                       "abcdefghijklmnopqrstuvwxyz" +
                       "abcdefghijklmnopqrstuvwxyz\n"
             };
             var obj       = JObject.FromObject(temp);
             var objString = obj.ToString(Formatting.None);
             var buffer    = Encoding.UTF8.GetBytes(objString);
             fixed(byte *pBuffer = buffer)
             {
                 parser.SetBuffer(pBuffer, buffer.Length);
                 using (var writer = new BlittableJsonDocumentBuilder(ctx,
                                                                      BlittableJsonDocumentBuilder.UsageMode.None,
                                                                      "test", parser, state))
                 {
                     writer.ReadObjectDocument();
                     var x = writer.Read();
                     writer.FinalizeDocument();
                     using (var reader = writer.CreateReader())
                         reader.BlittableValidation();
                 }
             }
         }
     }
 }
예제 #3
0
        public unsafe void Valid_object_read_from_non_zero_offset()
        {
            using (var context = JsonOperationContext.ShortTermSingleUse())
            {
                var jsonParserState = new JsonParserState();
                using (var parser = new UnmanagedJsonParser(context, jsonParserState, "changes/1"))
                {
                    byte[] buffer       = new byte[4096];
                    var    bufferOffset = 128; //non-zero offset

                    var allTokens = new AllTokensTypes
                    {
                        Bool     = true,
                        Float    = 123.4567F,
                        Int      = 45679123,
                        IntArray = new[] { 1, 2, 3 },
                        Null     = null,
                        Object   = new Empty(),
                        String   = "qwertyuio"
                    };
                    var obj       = JObject.FromObject(allTokens);
                    var objString = obj.ToString(Formatting.None);

                    var data = Encoding.UTF8.GetBytes(objString);

                    data.CopyTo(buffer, bufferOffset);

                    fixed(byte *pBuffer = buffer)
                    {
                        using (var builder = new BlittableJsonDocumentBuilder(context, BlittableJsonDocumentBuilder.UsageMode.None, "order/1", parser, jsonParserState))
                        {
                            parser.SetBuffer(pBuffer + bufferOffset, data.Length);

                            builder.ReadObjectDocument();

                            Assert.True(builder.Read());

                            builder.FinalizeDocument();

                            using (var reader = builder.CreateReader())
                            {
                                var value = reader.ToString();
                                Assert.NotNull(value);
                            }
                        }
                    }
                }
            }
        }
예제 #4
0
        private static unsafe BlittableJsonReaderObject ParseJsonAllAtOnce(string s, JsonOperationContext ctx)
        {
            var jsonParserState = new JsonParserState();
            var parser          = new UnmanagedJsonParser(ctx, jsonParserState, "test");
            var builder         = new BlittableJsonDocumentBuilder(ctx, BlittableJsonDocumentBuilder.UsageMode.ToDisk, "test", parser, jsonParserState);

            builder.ReadObjectDocument();
            var value = ctx.GetLazyString(s);

            parser.SetBuffer(value.Buffer, value.Size);
            Assert.True(builder.Read());
            builder.FinalizeDocument();
            var reader = builder.CreateReader();

            return(reader);
        }
        public void FailsOnInvalidJson(string invalidJson)
        {
            using (var ctx = JsonOperationContext.ShortTermSingleUse())
            {
                var buffer = Encoding.UTF8.GetBytes(invalidJson);
                var state  = new JsonParserState();
                fixed(byte *pBuffer = buffer)
                {
                    using (var parser = new UnmanagedJsonParser(ctx, state, "test"))
                    {
                        parser.SetBuffer(pBuffer, buffer.Length);
                        var writer = new BlittableJsonDocumentBuilder(ctx, BlittableJsonDocumentBuilder.UsageMode.ToDisk, "test", parser, state);

                        writer.ReadObjectDocument();
                        Assert.Throws <InvalidDataException>(() => writer.Read());
                    }
                }
            }
        }
예제 #6
0
        public static BlittableJsonReaderObject ParseToMemory(
            this JsonOperationContext.SyncJsonOperationContext syncContext,
            Stream stream,
            string debugTag,
            BlittableJsonDocumentBuilder.UsageMode mode,
            JsonOperationContext.MemoryBuffer bytes,
            IBlittableDocumentModifier modifier = null)
        {
            syncContext.EnsureNotDisposed();

            syncContext.JsonParserState.Reset();
            using (var parser = new UnmanagedJsonParser(syncContext.Context, syncContext.JsonParserState, debugTag))
                using (var builder = new BlittableJsonDocumentBuilder(syncContext.Context, mode, debugTag, parser, syncContext.JsonParserState, modifier: modifier))
                {
                    syncContext.Context.CachedProperties.NewDocument();
                    builder.ReadObjectDocument();
                    while (true)
                    {
                        if (bytes.Valid == bytes.Used)
                        {
                            var read = stream.Read(bytes.Memory.Memory.Span);
                            syncContext.EnsureNotDisposed();
                            if (read == 0)
                            {
                                throw new EndOfStreamException("Stream ended without reaching end of json content");
                            }
                            bytes.Valid = read;
                            bytes.Used  = 0;
                        }
                        parser.SetBuffer(bytes);
                        var result = builder.Read();
                        bytes.Used += parser.BufferOffset;
                        if (result)
                        {
                            break;
                        }
                    }
                    builder.FinalizeDocument();

                    var reader = builder.CreateReader();
                    return(reader);
                }
        }
예제 #7
0
        public BlittableJsonReaderObject ParseToMemory(Stream stream, string debugTag,
                                                       BlittableJsonDocumentBuilder.UsageMode mode,
                                                       ManagedPinnedBuffer bytes, IBlittableDocumentModifier modifier = null)
        {
            if (_disposed)
            {
                ThrowObjectDisposed();
            }

            _jsonParserState.Reset();
            using (var parser = new UnmanagedJsonParser(this, _jsonParserState, debugTag))
                using (var builder = new BlittableJsonDocumentBuilder(this, mode, debugTag, parser, _jsonParserState, modifier: modifier))
                {
                    CachedProperties.NewDocument();
                    builder.ReadObjectDocument();
                    while (true)
                    {
                        if (bytes.Valid == bytes.Used)
                        {
                            var read = stream.Read(bytes.Buffer.Array, bytes.Buffer.Offset, bytes.Length);
                            EnsureNotDisposed();
                            if (read == 0)
                            {
                                throw new EndOfStreamException("Stream ended without reaching end of json content");
                            }
                            bytes.Valid = read;
                            bytes.Used  = 0;
                        }
                        parser.SetBuffer(bytes);
                        var result = builder.Read();
                        bytes.Used += parser.BufferOffset;
                        if (result)
                        {
                            break;
                        }
                    }
                    builder.FinalizeDocument();

                    var reader = builder.CreateReader();
                    return(reader);
                }
        }
예제 #8
0
 public void CanReadAll(string name)
 {
     using (var ctx = JsonOperationContext.ShortTermSingleUse())
         using (var stream = typeof(UnmanageJsonReaderTests).GetTypeInfo().Assembly.GetManifestResourceStream(name))
             using (var parser = new UnmanagedJsonParser(ctx, new JsonParserState(), "test"))
             {
                 var buffer = new byte[4096];
                 fixed(byte *pBuffer = buffer)
                 {
                     while (stream.Position != stream.Length)
                     {
                         var read = stream.Read(buffer, 0, buffer.Length);
                         parser.SetBuffer(pBuffer, read);
                         while (parser.Read())
                         {
                         }
                     }
                 }
             }
 }
예제 #9
0
        public unsafe BlittableJsonReaderArray ParseBufferToArray(string value, string debugTag,
                                                                  BlittableJsonDocumentBuilder.UsageMode mode, IBlittableDocumentModifier modifier = null)
        {
            if (_disposed)
            {
                ThrowObjectDisposed();
            }

            _jsonParserState.Reset();
            using (var parser = new UnmanagedJsonParser(this, _jsonParserState, debugTag))
                using (var builder = new BlittableJsonDocumentBuilder(this, mode, debugTag, parser, _jsonParserState, modifier: modifier))
                    using (GetManagedBuffer(out var buffer))
                    {
                        CachedProperties.NewDocument();
                        builder.ReadArrayDocument();

                        var maxChars = buffer.Length / 8; //utf8 max size is 8 bytes, must consider worst case possiable

                        bool lastReadResult = false;
                        for (int i = 0; i < value.Length; i += maxChars)
                        {
                            var charsToRead = Math.Min(value.Length - i, maxChars);
                            var length      = Encodings.Utf8.GetBytes(value, i,
                                                                      charsToRead,
                                                                      buffer.Buffer.Array,
                                                                      buffer.Buffer.Offset);

                            parser.SetBuffer(buffer.Pointer, length);
                            lastReadResult = builder.Read();
                        }
                        if (lastReadResult == false)
                        {
                            throw new EndOfStreamException("Buffer ended without reaching end of json content");
                        }

                        builder.FinalizeDocument();

                        var reader = builder.CreateArrayReader(false);
                        return(reader);
                    }
        }
예제 #10
0
        private async Task <BlittableJsonReaderObject> ParseToMemoryAsync(Stream stream, string documentId, BlittableJsonDocumentBuilder.UsageMode mode)
        {
            _jsonParserState.Reset();
            ManagedPinnedBuffer bytes;

            using (GetManagedBuffer(out bytes))
                using (var parser = new UnmanagedJsonParser(this, _jsonParserState, documentId))
                {
                    var writer = new BlittableJsonDocumentBuilder(this, mode, documentId, parser, _jsonParserState);
                    try
                    {
                        CachedProperties.NewDocument();
                        writer.ReadObjectDocument();
                        while (true)
                        {
                            var read = await stream.ReadAsync(bytes.Buffer.Array, bytes.Buffer.Offset, bytes.Length);

                            if (read == 0)
                            {
                                throw new EndOfStreamException("Stream ended without reaching end of json content");
                            }
                            parser.SetBuffer(bytes, read);
                            if (writer.Read())
                            {
                                break;
                            }
                        }
                        writer.FinalizeDocument();

                        var reader = writer.CreateReader();
                        RegisterLiveReader(reader);

                        return(reader);
                    }
                    catch (Exception)
                    {
                        writer.Dispose();
                        throw;
                    }
                }
        }
예제 #11
0
        public async Task <BlittableJsonReaderArray> ParseArrayToMemoryAsync(Stream stream, string debugTag,
                                                                             BlittableJsonDocumentBuilder.UsageMode mode)
        {
            _jsonParserState.Reset();
            ManagedPinnedBuffer bytes;

            using (GetManagedBuffer(out bytes))
                using (var parser = new UnmanagedJsonParser(this, _jsonParserState, debugTag))
                {
                    var writer = new BlittableJsonDocumentBuilder(this, mode, debugTag, parser, _jsonParserState);
                    try
                    {
                        CachedProperties.NewDocument();
                        writer.ReadArrayDocument();
                        while (true)
                        {
                            var read = await stream.ReadAsync(bytes.Buffer.Array, bytes.Buffer.Offset, bytes.Length);

                            if (read == 0)
                            {
                                throw new EndOfStreamException("Stream ended without reaching end of json content");
                            }
                            parser.SetBuffer(bytes, read);
                            if (writer.Read())
                            {
                                break;
                            }
                        }
                        writer.FinalizeDocument();
                        // here we "leak" the memory used by the array, in practice this is used
                        // in short scoped context, so we don't care
                        return(writer.CreateArrayReader());
                    }
                    catch (Exception)
                    {
                        writer.Dispose();
                        throw;
                    }
                }
        }
        public async Task <BlittableJsonReaderArray> ParseArrayToMemoryAsync(Stream stream, string debugTag,
                                                                             BlittableJsonDocumentBuilder.UsageMode mode)
        {
            var state  = new JsonParserState();
            var buffer = GetParsingBuffer();

            using (var parser = new UnmanagedJsonParser(this, state, debugTag))
            {
                var writer = new BlittableJsonDocumentBuilder(this, mode, debugTag, parser, state);
                try
                {
                    CachedProperties.NewDocument();
                    writer.ReadArray();
                    while (true)
                    {
                        var read = await stream.ReadAsync(buffer, 0, buffer.Length);

                        if (read == 0)
                        {
                            throw new EndOfStreamException("Stream ended without reaching end of json content");
                        }
                        parser.SetBuffer(buffer, read);
                        if (writer.Read())
                        {
                            break;
                        }
                    }
                    writer.FinalizeDocument();
                    _disposables.Add(writer);
                    return(writer.CreateArrayReader());
                }
                catch (Exception)
                {
                    writer.Dispose();
                    throw;
                }
            }
        }
        private BlittableJsonReaderObject ParseToMemory(Stream stream, string debugTag, BlittableJsonDocumentBuilder.UsageMode mode)
        {
            var state  = new JsonParserState();
            var buffer = GetParsingBuffer();

            using (var parser = new UnmanagedJsonParser(this, state, debugTag))
            {
                var builder = new BlittableJsonDocumentBuilder(this, mode, debugTag, parser, state);
                try
                {
                    CachedProperties.NewDocument();
                    builder.ReadObject();
                    while (true)
                    {
                        var read = stream.Read(buffer, 0, buffer.Length);
                        if (read == 0)
                        {
                            throw new EndOfStreamException("Stream ended without reaching end of json content");
                        }
                        parser.SetBuffer(buffer, read);
                        if (builder.Read())
                        {
                            break;
                        }
                    }
                    builder.FinalizeDocument();

                    _disposables.Add(builder);
                    return(builder.CreateReader());
                }
                catch (Exception)
                {
                    builder.Dispose();
                    throw;
                }
            }
        }
예제 #14
0
        public async Task <BlittableJsonReaderObject> ReadFromWebSocket(
            WebSocket webSocket,
            string debugTag,
            CancellationToken cancellationToken)
        {
            if (_disposed)
            {
                ThrowObjectDisposed();
            }

            _jsonParserState.Reset();
            UnmanagedJsonParser          parser  = null;
            BlittableJsonDocumentBuilder builder = null;
            var managedBuffer = default(ReturnBuffer);
            var generation    = _generation;

            try
            {
                parser  = new UnmanagedJsonParser(this, _jsonParserState, debugTag);
                builder = new BlittableJsonDocumentBuilder(this,
                                                           BlittableJsonDocumentBuilder.UsageMode.None, debugTag, parser, _jsonParserState);
                managedBuffer = GetManagedBuffer(out var bytes);
                try
                {
                    builder.ReadObjectDocument();
                    var result = await webSocket.ReceiveAsync(bytes.Buffer, cancellationToken);

                    EnsureNotDisposed();

                    if (result.MessageType == WebSocketMessageType.Close)
                    {
                        return(null);
                    }
                    bytes.Valid = result.Count;
                    bytes.Used  = 0;

                    parser.SetBuffer(bytes);
                    while (true)
                    {
                        var read = builder.Read();
                        bytes.Used += parser.BufferOffset;
                        if (read)
                        {
                            break;
                        }
                        result = await webSocket.ReceiveAsync(bytes.Buffer, cancellationToken);

                        bytes.Valid = result.Count;
                        bytes.Used  = 0;
                        parser.SetBuffer(bytes);
                    }
                    builder.FinalizeDocument();
                    return(builder.CreateReader());
                }
                catch (Exception)
                {
                    builder.Dispose();
                    throw;
                }
            }
            finally
            {
                DisposeIfNeeded(generation, parser, builder);
                if (generation == _generation)
                {
                    managedBuffer.Dispose();
                }
            }
        }
예제 #15
0
        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
                        }
예제 #16
0
        public async Task <ImportResult> Import(DocumentsOperationContext context, Stream stream, Action <IOperationProgress> onProgress = null)
        {
            var result   = new ImportResult();
            var progress = new IndeterminateProgress();
            var state    = new JsonParserState();

            JsonOperationContext.ManagedPinnedBuffer buffer;
            using (context.GetManagedBuffer(out buffer))
                using (var parser = new UnmanagedJsonParser(context, state, "fileName"))
                {
                    var operateOnType = "__top_start_object";
                    var buildVersion  = 0L;
                    var identities    = new Dictionary <string, long>();
                    VersioningStorage versioningStorage = null;

                    while (true)
                    {
                        if (parser.Read() == false)
                        {
                            var read = await stream.ReadAsync(buffer.Buffer.Array, buffer.Buffer.Offset, buffer.Length);

                            if (read == 0)
                            {
                                if (state.CurrentTokenType != JsonParserToken.EndObject)
                                {
                                    throw new EndOfStreamException("Stream ended without reaching end of json content");
                                }
                                break;
                            }
                            parser.SetBuffer(buffer, read);
                            continue;
                        }

                        switch (state.CurrentTokenType)
                        {
                        case JsonParserToken.String:
                            unsafe
                            {
                                operateOnType =
                                    new LazyStringValue(null, state.StringBuffer, state.StringSize, context).ToString();
                            }
                            break;

                        case JsonParserToken.Integer:
                            switch (operateOnType)
                            {
                            case "BuildVersion":
                                buildVersion = state.Long;
                                break;
                            }
                            break;

                        case JsonParserToken.StartObject:
                            if (operateOnType == "__top_start_object")
                            {
                                operateOnType = null;
                                break;
                            }
                            context.CachedProperties.NewDocument();
                            var builder = new BlittableJsonDocumentBuilder(_batchPutCommand.Context, BlittableJsonDocumentBuilder.UsageMode.ToDisk, "ImportObject", parser, state);
                            builder.ReadNestedObject();
                            while (builder.Read() == false)
                            {
                                var read = await stream.ReadAsync(buffer.Buffer.Array, buffer.Buffer.Offset, buffer.Length);

                                if (read == 0)
                                {
                                    throw new EndOfStreamException("Stream ended without reaching end of json content");
                                }
                                parser.SetBuffer(buffer, read);
                            }
                            builder.FinalizeDocument();

                            if (operateOnType == "Docs" && Options.OperateOnTypes.HasFlag(DatabaseItemType.Documents))
                            {
                                progress.Progress = "Importing Documents";
                                onProgress?.Invoke(progress);
                                PatchDocument patch        = null;
                                PatchRequest  patchRequest = null;
                                if (string.IsNullOrWhiteSpace(Options.TransformScript) == false)
                                {
                                    patch        = new PatchDocument(context.DocumentDatabase);
                                    patchRequest = new PatchRequest
                                    {
                                        Script = Options.TransformScript
                                    };
                                }

                                result.DocumentsCount++;
                                var reader   = builder.CreateReader();
                                var document = new Document
                                {
                                    Data = reader,
                                };

                                if (Options.IncludeExpired == false && document.Expired(_database.Time.GetUtcNow()))
                                {
                                    continue;
                                }

                                TransformScriptOrDisableVersioningIfNeeded(context, patch, reader, document,
                                                                           patchRequest);

                                _batchPutCommand.Add(document.Data);

                                if (result.DocumentsCount % 1000 == 0)
                                {
                                    progress.Progress = $"Imported {result.DocumentsCount} documents";
                                    onProgress?.Invoke(progress);
                                }

                                await HandleBatchOfDocuments(context, parser, buildVersion).ConfigureAwait(false);
                            }
                            else if (operateOnType == "RevisionDocuments" &&
                                     Options.OperateOnTypes.HasFlag(DatabaseItemType.RevisionDocuments))
                            {
                                if (versioningStorage == null)
                                {
                                    break;
                                }

                                result.RevisionDocumentsCount++;
                                var reader = builder.CreateReader();
                                _batchPutCommand.Add(reader);
                                await HandleBatchOfDocuments(context, parser, buildVersion).ConfigureAwait(false);;
                            }
                            else
                            {
                                using (builder)
                                {
                                    switch (operateOnType)
                                    {
                                    case "Attachments":
                                        result.Warnings.Add("Attachments are not supported anymore. Use RavenFS isntead. Skipping.");
                                        break;

                                    case "Indexes":
                                        if (Options.OperateOnTypes.HasFlag(DatabaseItemType.Indexes) == false)
                                        {
                                            continue;
                                        }

                                        result.IndexesCount++;
                                        progress.Progress = "importing Indexes";
                                        onProgress?.Invoke(progress);
                                        try
                                        {
                                            IndexProcessor.Import(builder, _database, buildVersion, Options.RemoveAnalyzers);
                                        }
                                        catch (Exception e)
                                        {
                                            result.Warnings.Add($"Could not import index. Message: {e.Message}");
                                        }

                                        break;

                                    case "Transformers":
                                        if (Options.OperateOnTypes.HasFlag(DatabaseItemType.Transformers) == false)
                                        {
                                            continue;
                                        }

                                        result.TransformersCount++;
                                        progress.Progress = "Importing Transformers";
                                        onProgress?.Invoke(progress);

                                        try
                                        {
                                            TransformerProcessor.Import(builder, _database, buildVersion);
                                        }
                                        catch (Exception e)
                                        {
                                            result.Warnings.Add($"Could not import transformer. Message: {e.Message}");
                                        }
                                        break;

                                    case "Identities":
                                        if (Options.OperateOnTypes.HasFlag(DatabaseItemType.Identities))
                                        {
                                            result.IdentitiesCount++;
                                            progress.Progress = "Importing Identities";
                                            onProgress?.Invoke(progress);

                                            using (var reader = builder.CreateReader())
                                            {
                                                try
                                                {
                                                    string identityKey, identityValueString;
                                                    long   identityValue;
                                                    if (reader.TryGet("Key", out identityKey) == false || reader.TryGet("Value", out identityValueString) == false || long.TryParse(identityValueString, out identityValue) == false)
                                                    {
                                                        result.Warnings.Add($"Cannot import the following identity: '{reader}'. Skipping.");
                                                    }
                                                    else
                                                    {
                                                        identities[identityKey] = identityValue;
                                                    }
                                                }
                                                catch (Exception e)
                                                {
                                                    result.Warnings.Add($"Cannot import the following identity: '{reader}'. Error: {e}. Skipping.");
                                                }
                                            }
                                        }
                                        break;

                                    default:
                                        result.Warnings.Add(
                                            $"The following type is not recognized: '{operateOnType}'. Skipping.");
                                        break;
                                    }
                                }
                            }
                            break;

                        case JsonParserToken.StartArray:
                            switch (operateOnType)
                            {
                            case "RevisionDocuments":
                                // We are taking a reference here since the documents import can activate or disable the versioning.
                                // We hold a local copy because the user can disable the bundle during the import process, exteranly.
                                // In this case we want to continue to import the revisions documents.
                                versioningStorage           = _database.BundleLoader.VersioningStorage;
                                _batchPutCommand.IsRevision = true;
                                break;
                            }
                            break;

                        case JsonParserToken.EndArray:
                            switch (operateOnType)
                            {
                            case "Docs":
                                await FinishBatchOfDocuments();

                                _batchPutCommand = new MergedBatchPutCommand(_database, buildVersion);
                                break;

                            case "RevisionDocuments":
                                await FinishBatchOfDocuments();

                                break;

                            case "Identities":
                                if (identities.Count > 0)
                                {
                                    using (var tx = context.OpenWriteTransaction())
                                    {
                                        _database.DocumentsStorage.UpdateIdentities(context, identities);
                                        tx.Commit();
                                    }
                                }
                                identities = null;
                                break;
                            }
                            break;
                        }
                    }
                }

            return(result);
        }
예제 #17
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;
        }
예제 #18
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;
        }
예제 #19
0
 private unsafe void SetBuffer(UnmanagedJsonParser parser, LazyStringValue value)
 {
     parser.SetBuffer(value.Buffer, value.Size);
 }
예제 #20
0
        public async ValueTask <BlittableJsonReaderObject> ParseToMemoryAsync(Stream stream, string documentId, BlittableJsonDocumentBuilder.UsageMode mode, ManagedPinnedBuffer bytes,
                                                                              CancellationToken?token = null,
                                                                              int maxSize             = int.MaxValue)
        {
            if (_disposed)
            {
                ThrowObjectDisposed();
            }

            _jsonParserState.Reset();
            UnmanagedJsonParser          parser  = null;
            BlittableJsonDocumentBuilder builder = null;
            var generation     = _generation;
            var streamDisposer = token?.Register(stream.Dispose);

            try
            {
                parser  = new UnmanagedJsonParser(this, _jsonParserState, documentId);
                builder = new BlittableJsonDocumentBuilder(this, mode, documentId, parser, _jsonParserState);

                CachedProperties.NewDocument();
                builder.ReadObjectDocument();
                while (true)
                {
                    token?.ThrowIfCancellationRequested();
                    if (bytes.Valid == bytes.Used)
                    {
                        var read = token.HasValue
                            ? await stream.ReadAsync(bytes.Buffer.Array, bytes.Buffer.Offset, bytes.Length, token.Value)
                            : await stream.ReadAsync(bytes.Buffer.Array, bytes.Buffer.Offset, bytes.Length);

                        EnsureNotDisposed();

                        if (read == 0)
                        {
                            throw new EndOfStreamException("Stream ended without reaching end of json content");
                        }
                        bytes.Valid = read;
                        bytes.Used  = 0;
                        maxSize    -= read;
                        if (maxSize < 0)
                        {
                            throw new ArgumentException($"The maximum size allowed for {documentId} ({maxSize}) has been exceeded, aborting");
                        }
                    }
                    parser.SetBuffer(bytes);
                    var result = builder.Read();
                    bytes.Used += parser.BufferOffset;
                    if (result)
                    {
                        break;
                    }
                }
                builder.FinalizeDocument();

                var reader = builder.CreateReader();
                return(reader);
            }
            finally
            {
                streamDisposer?.Dispose();
                DisposeIfNeeded(generation, parser, builder);
            }
        }
예제 #21
0
        private void WriteToServer(string url, Stream serverStream)
        {
            const string debugTag        = "bulk/insert/document";
            var          jsonParserState = new JsonParserState();
            //var streamNetworkBuffer = new BufferedStream(serverStream, 32 * 1024);
            var streamNetworkBuffer = serverStream;
            var writeToStreamBuffer = new byte[32 * 1024];
            var header = Encoding.UTF8.GetBytes(RavenJObject.FromObject(new TcpConnectionHeaderMessage
            {
                DatabaseName = MultiDatabase.GetDatabaseName(url),
                Operation    = TcpConnectionHeaderMessage.OperationTypes.BulkInsert
            }).ToString());

            streamNetworkBuffer.Write(header, 0, header.Length);
            JsonOperationContext.ManagedPinnedBuffer bytes;
            using (_jsonOperationContext.GetManagedBuffer(out bytes))
            {
                while (_documents.IsCompleted == false)
                {
                    _cts.Token.ThrowIfCancellationRequested();

                    MemoryStream jsonBuffer;

                    try
                    {
                        jsonBuffer = _documents.Take();
                    }
                    catch (InvalidOperationException)
                    {
                        break;
                    }

                    var needToThrottle = _throttlingEvent.Wait(0) == false;

                    _jsonOperationContext.ResetAndRenew();
                    using (var jsonParser = new UnmanagedJsonParser(_jsonOperationContext, jsonParserState, debugTag))
                        using (var builder = new BlittableJsonDocumentBuilder(_jsonOperationContext,
                                                                              BlittableJsonDocumentBuilder.UsageMode.ToDisk, debugTag,
                                                                              jsonParser, jsonParserState))
                        {
                            _jsonOperationContext.CachedProperties.NewDocument();
                            builder.ReadObjectDocument();
                            while (true)
                            {
                                var read = jsonBuffer.Read(bytes.Buffer.Array, bytes.Buffer.Offset, bytes.Length);
                                if (read == 0)
                                {
                                    throw new EndOfStreamException("Stream ended without reaching end of json content");
                                }
                                jsonParser.SetBuffer(bytes, read);
                                if (builder.Read())
                                {
                                    break;
                                }
                            }
                            _buffers.Add(jsonBuffer);
                            builder.FinalizeDocument();
                            WriteVariableSizeInt(streamNetworkBuffer, builder.SizeInBytes);
                            WriteToStream(streamNetworkBuffer, builder, writeToStreamBuffer);
                        }

                    if (needToThrottle)
                    {
                        streamNetworkBuffer.Flush();
                        _throttlingEvent.Wait(500);
                    }
                }
                streamNetworkBuffer.WriteByte(0); //done
                streamNetworkBuffer.Flush();
            }
        }
예제 #22
0
        private async Task <BlittableJsonReaderObject> Receive(ClientWebSocket webSocket,
                                                               JsonOperationContext context)
        {
            BlittableJsonDocumentBuilder builder = null;

            try
            {
                if (webSocket.State != WebSocketState.Open)
                {
                    throw new InvalidOperationException(
                              $"Trying to 'ReceiveAsync' WebSocket while not in Open state. State is {webSocket.State}");
                }

                var state = new JsonParserState();
                JsonOperationContext.ManagedPinnedBuffer buffer;
                using (context.GetManagedBuffer(out buffer))
                    using (var parser = new UnmanagedJsonParser(context, state, "")) //TODO: FIXME
                    {
                        builder = new BlittableJsonDocumentBuilder(context, BlittableJsonDocumentBuilder.UsageMode.None,
                                                                   nameof(TrafficRec) + "." + nameof(Receive), parser, state);
                        builder.ReadObjectDocument();
                        while (builder.Read() == false)
                        {
                            var result = await webSocket.ReceiveAsync(buffer.Buffer, CancellationToken.None);

                            if (result.MessageType == WebSocketMessageType.Close)
                            {
                                if (_logger.IsInfoEnabled)
                                {
                                    _logger.Info("Client got close message from server and is closing connection");
                                }

                                builder.Dispose();
                                // actual socket close from dispose
                                return(null);
                            }

                            if (result.EndOfMessage == false)
                            {
                                throw new EndOfStreamException("Stream ended without reaching end of json content.");
                            }

                            parser.SetBuffer(buffer, 0, result.Count);
                        }
                        builder.FinalizeDocument();

                        return(builder.CreateReader());
                    }
            }
            catch (WebSocketException ex)
            {
                builder?.Dispose();

                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Failed to receive a message, client was probably disconnected", ex);
                }

                throw;
            }
        }
예제 #23
0
            public async Task <bool> MoveNextAsync()
            {
                var state = new JsonParserState();

                JsonOperationContext.ManagedPinnedBuffer buffer;

                using (var parser = new UnmanagedJsonParser(_session.Context, state, "stream contents"))
                    using (_session.Context.GetManagedBuffer(out buffer))
                    {
                        await ReadNextTokenAsync(_response.Stream, parser, buffer).ConfigureAwait(false);

                        if (state.CurrentTokenType != JsonParserToken.StartObject)
                        {
                            throw new InvalidOperationException("Expected stream to start, but got " +
                                                                state.CurrentTokenType);
                        }
                        await ReadNextTokenAsync(_response.Stream, parser, buffer).ConfigureAwait(false);

                        if (state.CurrentTokenType != JsonParserToken.String)
                        {
                            throw new InvalidOperationException("Expected stream intial property, but got " +
                                                                state.CurrentTokenType);
                        }

                        // TODO: Need to handle initial properties here from QueryHeaderInformation

                        var propery = GetPropertyName(state);
                        if (propery.Equals("Results") == false)
                        {
                            throw new InvalidOperationException("Expected stream property 'Results' but got " + propery);
                        }

                        await ReadNextTokenAsync(_response.Stream, parser, buffer).ConfigureAwait(false);

                        if (state.CurrentTokenType != JsonParserToken.StartArray)
                        {
                            throw new InvalidOperationException("Expected stream intial property, but got " +
                                                                state.CurrentTokenType);
                        }
                        await ReadNextTokenAsync(_response.Stream, parser, buffer).ConfigureAwait(false);

                        _session.Context.CachedProperties.NewDocument();
                        var builder = new BlittableJsonDocumentBuilder(_session.Context, BlittableJsonDocumentBuilder.UsageMode.ToDisk, "ImportObject", parser, state);
                        builder.ReadNestedObject();
                        while (builder.Read() == false)
                        {
                            var read = await _response.Stream.ReadAsync(buffer.Buffer.Array, buffer.Buffer.Offset, buffer.Length).ConfigureAwait(false);

                            if (read == 0)
                            {
                                throw new EndOfStreamException("Stream ended without reaching end of json content");
                            }
                            parser.SetBuffer(buffer, read);
                        }
                        builder.FinalizeDocument();
                        await ReadNextTokenAsync(_response.Stream, parser, buffer).ConfigureAwait(false);

                        Current = builder.CreateReader();

                        if (state.CurrentTokenType == JsonParserToken.EndArray)
                        {
                            await ReadNextTokenAsync(_response.Stream, parser, buffer).ConfigureAwait(false);

                            if (state.CurrentTokenType != JsonParserToken.EndObject)
                            {
                                throw new InvalidOperationException("Expected stream closing token, but got " +
                                                                    state.CurrentTokenType);
                            }
                            return(false);
                        }

                        await ReadNextTokenAsync(_response.Stream, parser, buffer).ConfigureAwait(false);

                        if (state.CurrentTokenType != JsonParserToken.EndObject)
                        {
                            throw new InvalidOperationException("Expected stream closing token, but got " +
                                                                state.CurrentTokenType);
                        }
                        return(true);
                    }
            }