private static ProduceResponse ReadProduceResponse(byte *b) { // ProduceResponse => [TopicName [Partition ErrorCode Offset Timestamp]] ThrottleTime // TopicName => string // Partition => int32 // ErrorCode => int16 // Offset => int64 // Timestamp => int64 // ThrottleTime => int32 ProduceResponse result = new ProduceResponse(); result.CorrelationId = IPAddress.NetworkToHostOrder(*((Int32 *)b)); b += 4; Int32 topicsLen = IPAddress.NetworkToHostOrder(*((Int32 *)b)); b += 4; result.TopicsInfo = new ProduceResponse.TopicInfo[topicsLen]; for (int i = 0; i < topicsLen; ++i) { result.TopicsInfo[i] = new ProduceResponse.TopicInfo(); Int16 topicLen = IPAddress.NetworkToHostOrder(*((Int16 *)b)); b += 2; result.TopicsInfo[i].Name = System.Text.Encoding.UTF8.GetString(b, topicLen); b += topicLen; Int32 partitionsLen = IPAddress.NetworkToHostOrder(*((Int32 *)b)); b += 4; result.TopicsInfo[i].PartitionsInfo = new ProduceResponse.PartitionInfo[partitionsLen]; for (int j = 0; j < partitionsLen; ++j) { result.TopicsInfo[i].PartitionsInfo[j] = new ProduceResponse.PartitionInfo(); result.TopicsInfo[i].PartitionsInfo[j].Partition = IPAddress.NetworkToHostOrder(*((Int32 *)b)); b += 4; result.TopicsInfo[i].PartitionsInfo[j].ErrorCode = (ErrorCode)IPAddress.NetworkToHostOrder(*((Int16 *)b)); b += 2; result.TopicsInfo[i].PartitionsInfo[j].Offset = IPAddress.NetworkToHostOrder(*((Int64 *)b)); b += 8; result.TopicsInfo[i].PartitionsInfo[j].Timestamp = IPAddress.NetworkToHostOrder(*((Int64 *)b)); b += 8; } } result.ThrottleTime = IPAddress.NetworkToHostOrder(*((Int32 *)b)); b += 4; return(result); }
private Task StartNetworkTask(CancellationToken ct) => Task.Factory.StartNew(() => { while (!ct.IsCancellationRequested) { Task.Delay(TimeSpan.FromMilliseconds(50)).Wait(); List <Buffer> addToInFlight = null; lock (forSendLock) { if (this.bufferPool.ForSend.Count > 0) { addToInFlight = new List <Buffer>(this.bufferPool.ForSend); this.bufferPool.ForSend.Clear(); this.bufferPool.InFlight.AddRange(addToInFlight); } } if (addToInFlight != null) { foreach (var b in addToInFlight) { client.Send(b.buffer, b.bufferCurrentPos); } } // TODO: do receive first, and prioritize over send (loop until none). if (!client.DataToReceive) { continue; } int correlationId; fixed(byte *bf = client.Receive()) { ProduceResponse pr = ReadProduceResponse(bf); this.ack(pr); correlationId = pr.CorrelationId; } Buffer receivedResponseFor = null; foreach (var b in this.bufferPool.InFlight) { if (b.correlationId == correlationId) { receivedResponseFor = b; break; } } if (receivedResponseFor == null) { throw new Exception("Unexpected correlation id"); } lock (freeForUseLock) { this.bufferPool.Move_InFlight_To_FreeForUse(receivedResponseFor); } } }, ct, TaskCreationOptions.LongRunning, TaskScheduler.Default);
static void ack(ProduceResponse r) { Console.WriteLine(r.TopicsInfo[0].PartitionsInfo[0].Offset); }