public byte[] JoinIfComplete(MessageChunk chunk) { var count = _store.CountChunks(chunk.OriginalMessageId); if (count >= chunk.ChunksCount - 1) { var chunks = _store.GetChunks(chunk.OriginalMessageId); if (chunks.ContainsKey(chunk.ChunkId)) { return(null); } chunks.Add(chunk.ChunkId, chunk.Content); var completeMessage = Join(chunks); _store.Cleanup(chunk.OriginalMessageId); return(completeMessage); } else { _store.Store(chunk); return(null); } }
public void Store(MessageChunk chunk) { lock (_lock) { // TODO: Log? if (DbSet.Any(c => c.OriginalMessageId == chunk.OriginalMessageId && c.ChunkId == chunk.ChunkId)) { return; } DbSet.Add(new TemporaryMessageChunk { OriginalMessageId = chunk.OriginalMessageId, ChunkId = chunk.ChunkId, ChunksCount = chunk.ChunksCount, Content = chunk.Content, Received = DateTime.UtcNow }); } }
public static IEnumerable <(object message, byte[] serializedMessage)> ChunkIfNeeded(string messageId, object message, ChunkSettings settings, IMessageSerializer serializer) { var serializedMessage = serializer.Serialize(message); var chunkSize = settings?.Size ?? int.MaxValue; if (chunkSize >= serializedMessage.Length) { yield return(message, serializedMessage); yield break; } if (string.IsNullOrEmpty(messageId)) { throw new InvalidOperationException( "Dividing into chunks is pointless if no unique MessageId can be retrieved. " + "Please add an Id or MessageId property to the message model or " + "use a custom IMessageKeyProvider."); } var span = serializedMessage.AsMemory(); var chunksCount = (int)Math.Ceiling(serializedMessage.Length / (double)chunkSize); var offset = 0; for (var i = 0; i < chunksCount; i++) { var messageChunk = new MessageChunk { MessageId = Guid.NewGuid(), OriginalMessageId = messageId, ChunkId = i, ChunksCount = chunksCount, Content = span.Slice(offset, Math.Min(chunkSize, serializedMessage.Length - offset)).ToArray() }; yield return(messageChunk, serializer.Serialize(messageChunk)); offset += chunkSize; } }