private async Task HandleErrors(string documentId, Exception e)
        {
            BulkInsertAbortedException errorFromServer = null;

            try
            {
                errorFromServer = await GetExceptionFromOperation().ConfigureAwait(false);
            }
            catch
            {
                // server is probably down, will propagate the original exception
            }

            if (errorFromServer != null)
            {
                throw errorFromServer;
            }

            await ThrowOnUnavailableStream(documentId, e).ConfigureAwait(false);
        }
Beispiel #2
0
        public async Task StoreAsync(object entity, string id, IMetadataDictionary metadata = null)
        {
            if (Interlocked.CompareExchange(ref _concurrentCheck, 1, 0) == 1)
            {
                throw new InvalidOperationException("Bulk Insert store methods cannot be executed concurrently.");
            }

            try
            {
                VerifyValidId(id);

                if (_stream == null)
                {
                    await WaitForId().ConfigureAwait(false);
                    await EnsureStream().ConfigureAwait(false);
                }

                if (_bulkInsertExecuteTask.IsFaulted)
                {
                    try
                    {
                        await _bulkInsertExecuteTask.ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        await ThrowBulkInsertAborted(e).ConfigureAwait(false);
                    }
                }

                if (metadata == null)
                {
                    metadata = new MetadataAsDictionary();
                }

                if (metadata.ContainsKey(Constants.Documents.Metadata.Collection) == false)
                {
                    var collection = _requestExecutor.Conventions.GetCollectionName(entity);
                    if (collection != null)
                    {
                        metadata.Add(Constants.Documents.Metadata.Collection, collection);
                    }
                }

                if (metadata.ContainsKey(Constants.Documents.Metadata.RavenClrType) == false)
                {
                    var clrType = _requestExecutor.Conventions.GetClrTypeName(entity);
                    if (clrType != null)
                    {
                        metadata[Constants.Documents.Metadata.RavenClrType] = clrType;
                    }
                }

                if (_first == false)
                {
                    _currentWriter.Write(',');
                }

                _first = false;
                try
                {
                    _currentWriter.Write("{\"Id\":\"");
                    WriteId(_currentWriter, id);
                    _currentWriter.Write("\",\"Type\":\"PUT\",\"Document\":");

                    _currentWriter.Flush();

                    if (_customEntitySerializer == null || _customEntitySerializer(entity, metadata, _currentWriter) == false)
                    {
                        using (var json = EntityToBlittable.ConvertEntityToBlittable(entity, _conventions, _context,
                                                                                     _defaultSerializer, new DocumentInfo
                        {
                            MetadataInstance = metadata
                        }))
                        {
                            json.WriteJsonTo(_currentWriter.BaseStream);
                        }
                    }

                    _currentWriter.Write("}");
                    _currentWriter.Flush();

                    if (_currentWriter.BaseStream.Position > _maxSizeInBuffer ||
                        _asyncWrite.IsCompleted)
                    {
                        await _asyncWrite.ConfigureAwait(false);

                        var tmp = _currentWriter;
                        _currentWriter    = _backgroundWriter;
                        _backgroundWriter = tmp;
                        _currentWriter.BaseStream.SetLength(0);
                        ((MemoryStream)tmp.BaseStream).TryGetBuffer(out var buffer);
                        _asyncWrite = _requestBodyStream.WriteAsync(buffer.Array, buffer.Offset, buffer.Count, _token);
                    }
                }
                catch (Exception e)
                {
                    BulkInsertAbortedException errorFromServer = null;
                    try
                    {
                        errorFromServer = await GetExceptionFromOperation().ConfigureAwait(false);
                    }
                    catch
                    {
                        // server is probably down, will propagate the original exception
                    }

                    if (errorFromServer != null)
                    {
                        throw errorFromServer;
                    }

                    await ThrowOnUnavailableStream(id, e).ConfigureAwait(false);
                }
            }
            finally
            {
                Interlocked.CompareExchange(ref _concurrentCheck, 0, 1);
            }

            void WriteId(StreamWriter writer, string input)
            {
                for (var i = 0; i < input.Length; i++)
                {
                    var c = input[i];
                    if (c == '"')
                    {
                        if (i == 0 || input[i - 1] != '\\')
                        {
                            writer.Write("\\");
                        }
                    }

                    writer.Write(c);
                }
            }
        }