Ejemplo n.º 1
0
		private async Task AppendInternalAsync(PendingWrite mine)
		{
			using (await _asyncLock.LockAsync())
			{
				var completed = new List<PendingWrite>();
				try
				{
					if (mine.Done())
						return;

					await MakeRoomForWrite(mine.Stream.Length, mine.Etag);

					var seq = _options.Status.NextSeqeunce();

					var room = _currentBufferSize - _memTable.MemTable.ApproximateMemoryUsage;

					PendingWrite write;
					while (_pending.TryDequeue(out write))
					{
						var memoryHandle = _memTable.MemTable.Write(write.Stream);

						await _memTable.Log.Write7BitEncodedIntAsync(memoryHandle.Size);

						using (var stream = _memTable.MemTable.Read(memoryHandle))
						{
							await _memTable.Log.CopyFromAsync(stream);
						}

						_memTable.MemTable.Add(seq, ItemType.Value, EtagToSlice(write.Etag), memoryHandle);

						room -= memoryHandle.Size;

						completed.Add(write);

						PendingWrite next;
						if (_pending.TryPeek(out next) == false)
							break;

						if (next.Stream.Length > room) // don't use more than the current mem table allows
							break;
					}

					foreach (var pendingWrite in completed)
					{
						pendingWrite.Result.SetResult(null);
					}
				}
				catch (Exception e)
				{
					foreach (var pendingWrite in completed)
					{
						pendingWrite.Result.SetException(e);
					}
					throw;
				}
				finally
				{
					_writeCompletedEvent.Pulse();
				}
			}
		}
Ejemplo n.º 2
0
		public async Task AppendAsync(RavenJObject data)
		{
			if (disposed)
				throw new ObjectDisposedException("EventStream");
			var nextEtag = _options.Status.NextEtag();
			data["@etag"] = nextEtag.ToString();
			data["@date"] = DateTime.UtcNow.ToString("o");

			using (var stream = new BufferPoolMemoryStream(_options.BufferPool))
			{
				var bsonWriter = new BsonWriter(stream);
				data.WriteTo(bsonWriter);
				bsonWriter.Flush();
				stream.Position = 0;
				var mine = new PendingWrite(stream, nextEtag);

				_pending.Enqueue(mine);

				while (mine.Done() == false && _pending.Peek() != mine)
				{
					await _writeCompletedEvent.WaitAsync();
				}

				if (mine.Done())
					return;

				await AppendInternalAsync(mine);
			}
		}