예제 #1
0
        public BulkInsertOperation(string database, IDocumentStore store, CancellationToken token = default)
        {
            _disposeOnce = new DisposeOnceAsync <SingleAttempt>(async() =>
            {
                try
                {
                    Exception flushEx = null;

                    if (_stream != null)
                    {
                        try
                        {
                            _currentWriter.Write(']');
                            _currentWriter.Flush();
                            await _asyncWrite.ConfigureAwait(false);
                            ((MemoryStream)_currentWriter.BaseStream).TryGetBuffer(out var buffer);
                            await _requestBodyStream.WriteAsync(buffer.Array, buffer.Offset, buffer.Count, _token).ConfigureAwait(false);
                            _compressedStream?.Dispose();
                            await _stream.FlushAsync(_token).ConfigureAwait(false);
                        }
                        catch (Exception e)
                        {
                            flushEx = e;
                        }
                    }

                    _streamExposerContent.Done();

                    if (_operationId == -1)
                    {
                        // closing without calling a single store.
                        return;
                    }

                    if (_bulkInsertExecuteTask != null)
                    {
                        try
                        {
                            await _bulkInsertExecuteTask.ConfigureAwait(false);
                        }
                        catch (Exception e)
                        {
                            await ThrowBulkInsertAborted(e, flushEx).ConfigureAwait(false);
                        }
                    }
                }
                finally
                {
                    _streamExposerContent?.Dispose();
                    _resetContext.Dispose();
                }
            });

            _token                = token;
            _conventions          = store.Conventions;
            _requestExecutor      = store.GetRequestExecutor(database);
            _resetContext         = _requestExecutor.ContextPool.AllocateOperationContext(out _context);
            _currentWriter        = new StreamWriter(new MemoryStream());
            _backgroundWriter     = new StreamWriter(new MemoryStream());
            _streamExposerContent = new StreamExposerContent();

            _defaultSerializer      = _requestExecutor.Conventions.CreateSerializer();
            _customEntitySerializer = _requestExecutor.Conventions.BulkInsert.TrySerializeEntityToJsonStream;

            _generateEntityIdOnTheClient = new GenerateEntityIdOnTheClient(_requestExecutor.Conventions,
                                                                           entity => AsyncHelpers.RunSync(() => _requestExecutor.Conventions.GenerateDocumentIdAsync(database, entity)));
        }
예제 #2
0
        public async Task DisposeAsync()
        {
            try
            {
                Exception flushEx = null;

                if (_stream != null)
                {
                    try
                    {
                        _jsonWriter.WriteEndArray();
                        _jsonWriter.Flush();
                        await _stream.FlushAsync(_token).ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        flushEx = e;
                    }
                }

                _streamExposerContent.Done();

                if (_operationId == -1)
                {
                    // closing without calling a single store.
                    return;
                }

                if (_bulkInsertExecuteTask != null)
                {
                    try
                    {
                        await _bulkInsertExecuteTask.ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        var errors = new List <Exception>(3)
                        {
                            e
                        };
                        if (flushEx != null)
                        {
                            errors.Add(flushEx);
                        }
                        var error = await GetExceptionFromOperation().ConfigureAwait(false);

                        if (error != null)
                        {
                            errors.Add(error);
                        }
                        errors.Reverse();
                        throw new BulkInsertAbortedException("Failed to execute bulk insert", new AggregateException(errors));
                    }
                }
            }
            finally
            {
                _streamExposerContent?.Dispose();
                _resetContext.Dispose();
            }
        }