public async Task ShouldBackoffRequestOnMultipleFailures(ErrorResponseCode errorCode) { var conn = Substitute.For<IKafkaConnection>(); conn.SendAsync(Arg.Any<IKafkaRequest<MetadataResponse>>()) .Returns(x => CreateMetadataResponse(errorCode), x => CreateMetadataResponse(errorCode), x => CreateMetadataResponse(errorCode), x => CreateMetadataResponse(ErrorResponseCode.NoError)); using (var provider = new KafkaMetadataProvider(_log)) { var response = await provider.Get(new[] { conn }, new[] { "Test" }); } Received.InOrder(() => { conn.SendAsync(Arg.Any<IKafkaRequest<MetadataResponse>>()).Wait(); _log.WarnFormat("Backing off metadata request retry. Waiting for {0}ms.", 100); conn.SendAsync(Arg.Any<IKafkaRequest<MetadataResponse>>()).Wait(); _log.WarnFormat("Backing off metadata request retry. Waiting for {0}ms.", 400); conn.SendAsync(Arg.Any<IKafkaRequest<MetadataResponse>>()).Wait(); _log.WarnFormat("Backing off metadata request retry. Waiting for {0}ms.", 900); conn.SendAsync(Arg.Any<IKafkaRequest<MetadataResponse>>()).Wait(); }); }
public async Task ShouldTryToRefreshMataDataIfCanRecoverByRefreshMetadata(ErrorResponseCode code) { var routerProxy = new BrokerRouterProxy(_kernel); routerProxy._cacheExpiration = new TimeSpan(10); var router = routerProxy.Create(); int partitionId = 0; ProtocolGateway protocolGateway = new ProtocolGateway(router); var fetchRequest = new FetchRequest(); bool sendExOnFirstTime = true; Func<Task<FetchResponse>> ShouldReturnErrorAndThenNoError = async () => { Task.Delay(routerProxy._cacheExpiration).Wait(); Task.Delay(1).Wait(); if (sendExOnFirstTime) { sendExOnFirstTime = false; return new FetchResponse() { Error = (short)code }; } return new FetchResponse() { Error = (short)ErrorResponseCode.NoError }; }; routerProxy.BrokerConn0.FetchResponseFunction = ShouldReturnErrorAndThenNoError; routerProxy.BrokerConn0.MetadataResponseFunction = BrokerRouterProxy.DefaultMetadataResponse; await protocolGateway.SendProtocolRequest(fetchRequest, BrokerRouterProxy.TestTopic, partitionId); Assert.That(routerProxy.BrokerConn0.MetadataRequestCallCount, Is.EqualTo(2)); Assert.That(routerProxy.BrokerConn0.FetchRequestCallCount, Is.EqualTo(2)); }
private Partition(ErrorResponseCode errorCode, int partitionId, int leaderId, int[] replicas, int[] isrs) { this.ErrorCode = errorCode; this.PartitionId = partitionId; this.LeaderId = leaderId; this.Replicas = replicas; this.Isrs = isrs; }
public static bool IsFromStaleMetadata(this ErrorResponseCode code) { return(code == ErrorResponseCode.UnknownTopicOrPartition || code == ErrorResponseCode.LeaderNotAvailable || code == ErrorResponseCode.NotLeaderForPartition || code == ErrorResponseCode.GroupLoadInProgress || code == ErrorResponseCode.GroupCoordinatorNotAvailable || code == ErrorResponseCode.NotCoordinatorForGroup); }
public Partition(int partitionId, int leaderId, ErrorResponseCode errorCode = ErrorResponseCode.None, IEnumerable <int> replicas = null, IEnumerable <int> isrs = null) { ErrorCode = errorCode; PartitionId = partitionId; LeaderId = leaderId; Replicas = ImmutableList <int> .Empty.AddNotNullRange(replicas); Isrs = ImmutableList <int> .Empty.AddNotNullRange(isrs); }
public Group(ErrorResponseCode errorCode, string groupId, string state, string protocolType, string protocol, IEnumerable <Member> members) { ErrorCode = errorCode; GroupId = groupId; State = state; ProtocolType = protocolType; Protocol = protocol; Members = ImmutableList <Member> .Empty.AddNotNullRange(members); }
public void LeaveGroupResponse( [Values( ErrorResponseCode.None, ErrorResponseCode.OffsetMetadataTooLarge )] ErrorResponseCode errorCode) { var response = new LeaveGroupResponse(errorCode); response.AssertCanEncodeDecodeResponse(0); }
public JoinGroupResponse(ErrorResponseCode errorCode, int generationId, string groupProtocol, string leaderId, string memberId, IEnumerable <Member> members) { ErrorCode = errorCode; Errors = ImmutableList <ErrorResponseCode> .Empty.Add(ErrorCode); GenerationId = generationId; GroupProtocol = groupProtocol; LeaderId = leaderId; MemberId = memberId; Members = ImmutableList <Member> .Empty.AddNotNullRange(members); }
public async Task ShouldThrowExceptionWhenNotARetriableErrorCode(ErrorResponseCode errorCode) { var conn = Substitute.For <IKafkaConnection>(); conn.SendAsync(Arg.Any <IKafkaRequest <MetadataResponse> >()).Returns(x => CreateMetadataResponse(errorCode)); using (var provider = new KafkaMetadataProvider(_log)) { var response = await provider.Get(new[] { conn }, new[] { "Test" }); } }
public async Task ShouldThrowExceptionWhenNotARetriableErrorCode(ErrorResponseCode errorCode) { var conn = Substitute.For <IConnection>(); conn.SendAsync(Arg.Any <IRequest <MetadataResponse> >(), Arg.Any <CancellationToken>()).Returns(x => CreateMetadataResponse(errorCode)); _brokerRouter.Connections.ReturnsForAnyArgs(new List <IConnection> { conn }); Assert.ThrowsAsync <RequestException>(() => _brokerRouter.GetMetadataAsync(new [] { "Test" }, CancellationToken.None)); }
public async Task SendProtocolRequestShouldNotTryToRefreshMataDataIfCanNotRecoverByRefreshMetadata( ErrorResponseCode code) { var routerProxy = new BrokerRouterProxy(); routerProxy.CacheExpiration = TimeSpan.FromMilliseconds(10); var router = routerProxy.Create(); routerProxy.Connection1.FetchResponseFunction = FailedInFirstMessageError(code, routerProxy.CacheExpiration); routerProxy.Connection1.MetadataResponseFunction = BrokerRouterProxy.CreateMetadataResponseWithMultipleBrokers; Assert.ThrowsAsync <RequestException>(async() => await router.SendAsync(new FetchRequest(), BrokerRouterProxy.TestTopic, PartitionId, CancellationToken.None)); }
public void SaslHandshakeResponse( [Values( ErrorResponseCode.None, ErrorResponseCode.OffsetMetadataTooLarge )] ErrorResponseCode errorCode, [Range(1, 11)] int count) { var mechanisms = new[] { "EXTERNAL", "ANONYMOUS", "PLAIN", "OTP", "SKEY", "CRAM-MD5", "DIGEST-MD5", "SCRAM", "NTLM", "GSSAPI", "OAUTHBEARER" }; var response = new SaslHandshakeResponse(errorCode, mechanisms.Take(count)); response.AssertCanEncodeDecodeResponse(0); }
public void SyncGroupResponse( [Values( ErrorResponseCode.None, ErrorResponseCode.OffsetMetadataTooLarge )] ErrorResponseCode errorCode) { var bytes = new byte[1000]; _randomizer.NextBytes(bytes); var response = new SyncGroupResponse(errorCode, new ByteMember(bytes)); response.AssertCanEncodeDecodeResponse(0); }
public async Task SendProtocolRequestShouldNoTryToRefreshMataDataIfCanNotRecoverByRefreshMetadata( ErrorResponseCode code) { var routerProxy = new BrokerRouterProxy(_kernel); routerProxy._cacheExpiration = TimeSpan.FromMilliseconds(10); var router = routerProxy.Create(); ProtocolGateway protocolGateway = new ProtocolGateway(router); routerProxy.BrokerConn0.FetchResponseFunction = FailedInFirstMessageError(code, routerProxy._cacheExpiration); routerProxy.BrokerConn0.MetadataResponseFunction = BrokerRouterProxy.CreateMetadataResponseWithMultipleBrokers; await protocolGateway.SendProtocolRequest(new FetchRequest(), BrokerRouterProxy.TestTopic, _partitionId); }
public void GroupCoordinatorResponse( [Values( ErrorResponseCode.None, ErrorResponseCode.GroupCoordinatorNotAvailable, ErrorResponseCode.GroupAuthorizationFailed )] ErrorResponseCode errorCode, [Values(0, 1)] int coordinatorId ) { var response = new GroupCoordinatorResponse(errorCode, coordinatorId, "broker-" + coordinatorId, 9092 + coordinatorId); response.AssertCanEncodeDecodeResponse(0); }
/// <summary> /// See http://kafka.apache.org/protocol.html#protocol_error_codes for details /// </summary> public static bool IsRetryable(this ErrorResponseCode code) { return(code == ErrorResponseCode.CorruptMessage || code == ErrorResponseCode.UnknownTopicOrPartition || code == ErrorResponseCode.LeaderNotAvailable || code == ErrorResponseCode.NotLeaderForPartition || code == ErrorResponseCode.RequestTimedOut || code == ErrorResponseCode.NetworkException || code == ErrorResponseCode.GroupLoadInProgress || code == ErrorResponseCode.GroupCoordinatorNotAvailable || code == ErrorResponseCode.NotCoordinatorForGroup || code == ErrorResponseCode.NotEnoughReplicas || code == ErrorResponseCode.NotEnoughReplicasAfterAppend || code == ErrorResponseCode.NotController); }
public async Task ShouldTryToRefreshMataDataIfCanRecoverByRefreshMetadata(ErrorResponseCode code) { var routerProxy = new BrokerRouterProxy(); routerProxy.CacheExpiration = new TimeSpan(10); var router = routerProxy.Create(); routerProxy.Connection1.FetchResponseFunction = FailedInFirstMessageError(code, routerProxy.CacheExpiration); routerProxy.Connection1.MetadataResponseFunction = BrokerRouterProxy.CreateMetadataResponseWithMultipleBrokers; await router.SendAsync(new FetchRequest(), BrokerRouterProxy.TestTopic, PartitionId, CancellationToken.None); Assert.That(routerProxy.Connection1.MetadataRequestCallCount, Is.EqualTo(2)); Assert.That(routerProxy.Connection1.FetchRequestCallCount, Is.EqualTo(2)); }
public async Task ShouldTryToRefreshMataDataIfCanRecoverByRefreshMetadata(ErrorResponseCode code) { var routerProxy = new BrokerRouterProxy(_kernel); routerProxy._cacheExpiration = new TimeSpan(10); var router = routerProxy.Create(); ProtocolGateway protocolGateway = new ProtocolGateway(router); routerProxy.BrokerConn0.FetchResponseFunction = FailedInFirstMessageError(code, routerProxy._cacheExpiration); routerProxy.BrokerConn0.MetadataResponseFunction = BrokerRouterProxy.CreateMetadataResponseWithMultipleBrokers; await protocolGateway.SendProtocolRequest(new FetchRequest(), BrokerRouterProxy.TestTopic, _partitionId); Assert.That(routerProxy.BrokerConn0.MetadataRequestCallCount, Is.EqualTo(2)); Assert.That(routerProxy.BrokerConn0.FetchRequestCallCount, Is.EqualTo(2)); }
public void ApiVersionsResponse( [Values( ErrorResponseCode.None, ErrorResponseCode.BrokerNotAvailable )] ErrorResponseCode errorCode ) { var supported = new List <ApiVersionsResponse.VersionSupport>(); for (short apiKey = 0; apiKey <= 18; apiKey++) { supported.Add(new ApiVersionsResponse.VersionSupport((ApiKeyRequestType)apiKey, 0, (short)_randomizer.Next(0, 2))); } var response = new ApiVersionsResponse(errorCode, supported); response.AssertCanEncodeDecodeResponse(0); }
public void DeleteTopicsResponse( [Values( ErrorResponseCode.None, ErrorResponseCode.NotController )] ErrorResponseCode errorCode, [Values("test", "anotherNameForATopic")] string topicName, [Range(1, 11)] int count) { var topics = new TopicsResponse.Topic[count]; for (var t = 0; t < count; t++) { topics[t] = new TopicsResponse.Topic(topicName + t, errorCode); } var response = new DeleteTopicsResponse(topics); response.AssertCanEncodeDecodeResponse(0); }
private static Func <Task <FetchResponse> > FailedInFirstMessageError(ErrorResponseCode errorResponseCode, TimeSpan delay) { bool firstTime = true; Func <Task <FetchResponse> > result = async() => { if (firstTime) { await Task.Delay(delay); await Task.Delay(1); firstTime = false; return(new FetchResponse(new [] { new FetchResponse.Topic("foo", 1, 0, errorResponseCode) })); } return(new FetchResponse()); }; return(result); }
private async Task <List <MetadataResponse> > CreateMetadataResponse(ErrorResponseCode errorCode) { return(new List <MetadataResponse> { new MetadataResponse { Brokers = new List <Broker>(), Topics = new List <Topic> { new Topic { ErrorCode = (short)errorCode, Name = "Test", Partitions = new List <Partition>() } } } }); }
public async Task ShouldRetryWhenReceiveAnRetryErrorCode(ErrorResponseCode errorCode) { var conn = Substitute.For <IKafkaConnection>(); conn.SendAsync(Arg.Any <IKafkaRequest <MetadataResponse> >()) .Returns(x => CreateMetadataResponse(errorCode), x => CreateMetadataResponse(errorCode)); using (var provider = new KafkaMetadataProvider(_log)) { var response = await provider.Get(new[] { conn }, new[] { "Test" }); } Received.InOrder(() => { conn.SendAsync(Arg.Any <IKafkaRequest <MetadataResponse> >()); _log.WarnFormat("Backing off metadata request retry. Waiting for {0}ms.", 100); conn.SendAsync(Arg.Any <IKafkaRequest <MetadataResponse> >()); }); }
public void ListGroupsResponse( [Values( ErrorResponseCode.None, ErrorResponseCode.OffsetMetadataTooLarge )] ErrorResponseCode errorCode, [Values("test", "a groupId")] string groupId, [Range(2, 3)] int count, [Values("consumer")] string protocolType) { var groups = new ListGroupsResponse.Group[count]; for (var g = 0; g < count; g++) { groups[g] = new ListGroupsResponse.Group(groupId + g, protocolType); } var response = new ListGroupsResponse(errorCode, groups); response.AssertCanEncodeDecodeResponse(0); }
public void SyncConsumerGroupResponse( [Values( ErrorResponseCode.None, ErrorResponseCode.OffsetMetadataTooLarge )] ErrorResponseCode errorCode, [Values(1, 10)] int memberCount) { var encoder = new ConsumerEncoder(); var topics = new List <TopicPartition>(); for (var t = 0; t < memberCount; t++) { topics.Add(new TopicPartition("topic foo" + t, t)); } var assignment = new ConsumerMemberAssignment(0, topics); var response = new SyncGroupResponse(errorCode, assignment); response.AssertCanEncodeDecodeResponse(0, encoder); }
public void MetadataResponse( [Values(0, 1, 2)] short version, [Values(1, 15)] int brokersPerRequest, [Values("test", "a really long name, with spaces and punctuation!")] string topicName, [Values(1, 10)] int topicsPerRequest, [Values(1, 5)] int partitionsPerTopic, [Values( ErrorResponseCode.None, ErrorResponseCode.UnknownTopicOrPartition )] ErrorResponseCode errorCode) { var brokers = new List <Broker>(); for (var b = 0; b < brokersPerRequest; b++) { string rack = null; if (version >= 1) { rack = "Rack" + b; } brokers.Add(new Broker(b, "broker-" + b, 9092 + b, rack)); } var topics = new List <MetadataResponse.Topic>(); for (var t = 0; t < topicsPerRequest; t++) { var partitions = new List <MetadataResponse.Partition>(); for (var partitionId = 0; partitionId < partitionsPerTopic; partitionId++) { var leader = _randomizer.Next(0, brokersPerRequest - 1); var replica = 0; var replicas = _randomizer.Next(0, brokersPerRequest - 1).Repeat(() => replica++); var isr = 0; var isrs = _randomizer.Next(0, replica).Repeat(() => isr++); partitions.Add(new MetadataResponse.Partition(partitionId, leader, errorCode, replicas, isrs)); } topics.Add(new MetadataResponse.Topic(topicName + t, errorCode, partitions, version >= 1 ? topicsPerRequest % 2 == 0 : (bool?)null)); } var response = new MetadataResponse(brokers, topics, version >= 1 ? brokersPerRequest : (int?)null, version >= 2 ? $"cluster-{version}" : null); response.AssertCanEncodeDecodeResponse(version); }
private Task <List <MetadataResponse> > CreateMetadataResponse(ErrorResponseCode errorCode) { var tcs = new TaskCompletionSource <List <MetadataResponse> >(); tcs.SetResult(new List <MetadataResponse> { new MetadataResponse { Brokers = new List <Broker>(), Topics = new List <Topic> { new Topic { ErrorCode = (short)errorCode, Name = "Test", Partitions = new List <Partition>() } } } }); return(tcs.Task); }
public void DescribeConsumerGroupsResponse( [Values( ErrorResponseCode.None, ErrorResponseCode.OffsetMetadataTooLarge )] ErrorResponseCode errorCode, [Values("test", "a groupId")] string groupId, [Range(2, 3)] int count, [Values(KafkaClient.Protocol.DescribeGroupsResponse.Group.States.Stable, KafkaClient.Protocol.DescribeGroupsResponse.Group.States.AwaitingSync)] string state, [Values("consumer")] string protocolType, [Values("good", "bad", "ugly")] string protocol) { var encoder = new ConsumerEncoder(); var groups = new DescribeGroupsResponse.Group[count]; for (var g = 0; g < count; g++) { var members = new List <DescribeGroupsResponse.Member>(); for (var m = 0; m < count; m++) { var memberId = "member" + m; var userData = new byte[count * 100]; _randomizer.NextBytes(userData); var metadata = new ConsumerProtocolMetadata(0, new [] { protocol, memberId, memberId }, userData); var topics = new List <TopicPartition>(); for (var t = 0; t < count; t++) { topics.Add(new TopicPartition("topic foo" + t, t)); } var assignment = new ConsumerMemberAssignment(0, topics); members.Add(new DescribeGroupsResponse.Member(memberId, "client" + m, "host-" + m, metadata, assignment)); } groups[g] = new DescribeGroupsResponse.Group(errorCode, groupId + g, state, protocolType, protocol, members); } var response = new DescribeGroupsResponse(groups); response.AssertCanEncodeDecodeResponse(0, encoder); }
public void ProduceResponse( [Values(0, 1, 2)] short version, [Values(-1, 0, 10000000)] long timestampMilliseconds, [Values("test", "a really long name, with spaces and punctuation!")] string topicName, [Values(1, 10)] int topicsPerRequest, [Values(1, 5)] int totalPartitions, [Values( ErrorResponseCode.None, ErrorResponseCode.CorruptMessage )] ErrorResponseCode errorCode, [Values(0, 100000)] int throttleTime) { var topics = new List <ProduceResponse.Topic>(); for (var t = 0; t < topicsPerRequest; t++) { topics.Add(new ProduceResponse.Topic(topicName + t, t % totalPartitions, errorCode, _randomizer.Next(), version >= 2 ? timestampMilliseconds.FromUnixEpochMilliseconds() : (DateTime?)null)); } var response = new ProduceResponse(topics, version >= 1 ? TimeSpan.FromMilliseconds(throttleTime) : (TimeSpan?)null); response.AssertCanEncodeDecodeResponse(version); }
public override void DealWithParserError(string p_Error) { // TODO: 如果 enum parse 失敗,會丟出Exception ErrorResponseCode parserError = (ErrorResponseCode)Enum.Parse(typeof(ErrorResponseCode), p_Error); char[] errorResopnse = new char[1 + 1]; switch (parserError) { case ErrorResponseCode.CRCError: errorResopnse[0] = (char)ReplyCommand.ErrorResponse; errorResopnse[1] = (char)ErrorResponseCode.CRCError; m_Interface.ReplyMessage(new string(errorResopnse)); break; case ErrorResponseCode.UnknowCommandError: errorResopnse[0] = (char)ReplyCommand.ErrorResponse; errorResopnse[1] = (char)ErrorResponseCode.UnknowCommandError; m_Interface.ReplyMessage(new string(errorResopnse)); break; } }
public void OffsetCommitResponse( [Values("test", "a really long name, with spaces and punctuation!")] string topicName, [Values(1, 10)] int topicsPerRequest, [Values(1, 5)] int partitionsPerTopic, [Values( ErrorResponseCode.None, ErrorResponseCode.OffsetMetadataTooLarge )] ErrorResponseCode errorCode) { var topics = new List <TopicResponse>(); for (var t = 0; t < topicsPerRequest; t++) { for (var partitionId = 0; partitionId < partitionsPerTopic; partitionId++) { topics.Add(new TopicResponse(topicName + t, partitionId, errorCode)); } } var response = new OffsetCommitResponse(topics); response.AssertCanEncodeDecodeResponse(0); }
public void JoinGroupResponse( [Values( ErrorResponseCode.None, ErrorResponseCode.OffsetMetadataTooLarge )] ErrorResponseCode errorCode, [Values(0, 1, 20000)] int generationId, [Values("consumer", "other")] string protocol, [Values("test", "a groupId")] string leaderId, [Values("", "an existing member")] string memberId, [Values(1, 10)] int memberCount) { var members = new List <JoinGroupResponse.Member>(); for (var m = 0; m < memberCount; m++) { var bytes = new byte[memberCount * 100]; _randomizer.NextBytes(bytes); members.Add(new JoinGroupResponse.Member(memberId + m, new ByteMember(bytes))); } var response = new JoinGroupResponse(errorCode, generationId, protocol, leaderId, memberId, members); response.AssertCanEncodeDecodeResponse(0); }
public async Task ShouldThrowExceptionWhenNotARetriableErrorCode(ErrorResponseCode errorCode) { var conn = Substitute.For<IKafkaConnection>(); conn.SendAsync(Arg.Any<IKafkaRequest<MetadataResponse>>()).Returns(x => CreateMetadataResponse(errorCode)); using (var provider = new KafkaMetadataProvider(_log)) { var response = await provider.Get(new[] { conn }, new[] { "Test" }); } }
private async Task<List<MetadataResponse>> CreateMetadataResponse(ErrorResponseCode errorCode) { return new List<MetadataResponse> { new MetadataResponse { Brokers = new List<Broker>(), Topics = new List<Topic> { new Topic { ErrorCode = (short) errorCode, Name = "Test", Partitions = new List<Partition>() } } } }; }
public Topic(string topic, int partitionId, long highWaterMark, ErrorResponseCode errorCode = ErrorResponseCode.None, IEnumerable <Message> messages = null) : base(topic, partitionId, errorCode) { HighWaterMark = highWaterMark; Messages = ImmutableList <Message> .Empty.AddNotNullRange(messages); }
public InvalidTopicMetadataException(SerializationInfo info, StreamingContext context) : base(info, context) { ErrorResponseCode = (ErrorResponseCode)info.GetInt16("ErrorResponseCode"); }
private Task<List<MetadataResponse>> CreateMetadataResponse(ErrorResponseCode errorCode) { var tcs = new TaskCompletionSource<List<MetadataResponse>>(); tcs.SetResult(new List<MetadataResponse>{ new MetadataResponse { Brokers = new List<Broker>(), Topics = new List<Topic> { new Topic { ErrorCode = (short) errorCode, Name = "Test", Partitions = new List<Partition>() } } }}); return tcs.Task; }
private Topic(ErrorResponseCode errorCode, string name, Partition[] partitions) { this.ErrorCode = errorCode; this.Name = name; this.Partitions = partitions; }
public async Task SendProtocolRequestShouldNoTryToRefreshMataDataIfCanNotRecoverByRefreshMetadata(ErrorResponseCode code) { var routerProxy = new BrokerRouterProxy(_kernel); routerProxy._cacheExpiration = TimeSpan.FromMilliseconds(10); var router = routerProxy.Create(); int partitionId = 0; ProtocolGateway protocolGateway = new ProtocolGateway(router); var fetchRequest = new FetchRequest(); bool firstTime = true; Func<Task<FetchResponse>> ShouldReturnError = async () => { if (firstTime) { firstTime = !firstTime; return new FetchResponse() { Error = (short)code }; } return new FetchResponse() { Error = (short)ErrorResponseCode.NoError }; }; routerProxy.BrokerConn0.FetchResponseFunction = ShouldReturnError; routerProxy.BrokerConn0.MetadataResponseFunction = BrokerRouterProxy.DefaultMetadataResponse; await protocolGateway.SendProtocolRequest(fetchRequest, BrokerRouterProxy.TestTopic, partitionId); }
private static Func<Task<FetchResponse>> FailedInFirstMessageError(ErrorResponseCode errorResponseCode, TimeSpan delay) { bool firstTime = true; Func<Task<FetchResponse>> result = async () => { if (firstTime) { await Task.Delay(delay); await Task.Delay(1); firstTime = false; return new FetchResponse() { Error = (short)errorResponseCode }; } return new FetchResponse() { Error = (short)ErrorResponseCode.NoError }; }; return result; }
public InvalidTopicMetadataException(ErrorResponseCode code, string message, params object[] args) : base(string.Format(message, args)) { ErrorResponseCode = code; }