예제 #1
0
        private async ValueTask SubscribeToTopic(Subscribe sub)
        {
            try
            {
                var response = await _consumer.Ask <AskResponse>(sub).ConfigureAwait(false);

                _sender.Tell(response);
            }
            catch (Exception ex)
            {
                _sender.Tell(new AskResponse(PulsarClientException.Unwrap(ex)));
            }
        }
        public AskResponse(PulsarClientException exception)
        {
            if (exception == null)
            {
                Failed = false;
            }
            else
            {
                Failed = true;
            }

            Exception = exception;
        }
예제 #3
0
        private async ValueTask <IMessage <T> > FetchSingleMessageFromBroker()
        {
            // Just being cautious
            if (IncomingMessages.Count > 0)
            {
                _log.Error("The incoming message queue should never be greater than 0 when Queue size is 0");
                IncomingMessages.Empty();
            }

            IMessage <T> message;

            try
            {
                // if cnx is null or if the connection breaks the connectionOpened function will send the flow again
                _waitingOnReceiveForZeroQueueSize = true;
                if (Connected())
                {
                    IncreaseAvailablePermits(_clientCnx);
                }
                do
                {
                    message = await IncomingMessages.ReceiveAsync();

                    _lastDequeuedMessageId = message.MessageId;
                    var msgCnx = ((Message <T>)message).Cnx();
                    // synchronized need to prevent race between connectionOpened and the check "msgCnx == cnx()"
                    // if message received due to an old flow - discard it and wait for the message from the
                    // latest flow command
                    if (msgCnx == _clientCnx)
                    {
                        _waitingOnReceiveForZeroQueueSize = false;
                        break;
                    }
                } while(true);

                Stats.UpdateNumMsgsReceived(message);
                return(message);
            }
            catch (Exception e)
            {
                Stats.IncrementNumReceiveFailed();
                throw PulsarClientException.Unwrap(e);
            }
            finally
            {
                // Finally blocked is invoked in case the block on incomingMessages is interrupted
                _waitingOnReceiveForZeroQueueSize = false;
                // Clearing the queue in case there was a race with messageReceived
                IncomingMessages.Empty();
            }
        }
예제 #4
0
        private async ValueTask GetTopicsUnderNamespace(NamespaceName ns, Mode mode, TimeSpan opTimeout)
        {
            try
            {
                var request     = Commands.NewGetTopicsOfNamespaceRequest(ns.ToString(), _requestId, mode);
                var payload     = new Payload(request, _requestId, "NewGetTopicsOfNamespaceRequest");
                var askResponse = await _clientCnx.Ask <AskResponse>(payload, TimeSpan.FromSeconds(10));

                var response = askResponse.ConvertTo <GetTopicsOfNamespaceResponse>();
                if (_log.IsDebugEnabled)
                {
                    _log.Debug($"[namespace: {ns}] Successfully got {response.Response.Topics.Count} topics list in request: {_requestId}");
                }
                var result = new List <string>();
                var tpics  = response.Response.Topics.Where(x => !x.Contains("__transaction")).ToArray();
                foreach (var topic in tpics)
                {
                    var filtered = TopicName.Get(topic).PartitionedTopicName;
                    if (!result.Contains(filtered))
                    {
                        result.Add(filtered);
                    }
                }
                _replyTo.Tell(new AskResponse(new GetTopicsUnderNamespaceResponse(result)));
            }
            catch
            {
                var nextDelay = Math.Min(_getTopicsUnderNamespaceBackOff.Next(), opTimeout.TotalMilliseconds);
                var reply     = _replyTo;
                if (nextDelay <= 0)
                {
                    reply.Tell(new AskResponse(PulsarClientException.Unwrap(new Exception($"TimeoutException: Could not get topics of namespace {ns} within configured timeout"))));
                }
                else
                {
                    _log.Warning($"[namespace: {ns}] Could not get connection while getTopicsUnderNamespace -- Will try again in {nextDelay} ms");
                    opTimeout.Subtract(TimeSpan.FromMilliseconds(nextDelay));
                    await Task.Delay(TimeSpan.FromMilliseconds(nextDelay));

                    var reqId = await _generator.Ask <NewRequestIdResponse>(NewRequestId.Instance);

                    _requestId = reqId.Id;

                    _log.Warning($"Retrying 'GetTopicsUnderNamespace' after {nextDelay} ms delay with requestid '{reqId.Id}'");

                    await GetTopicsUnderNamespace(ns, mode, opTimeout);
                }
            }
        }
예제 #5
0
 private void Listen()
 {
     ReceiveAsync <GetConnection>(async g =>
     {
         try
         {
             ConnectionOpened connection = null;
             _randomKey       = SignSafeMod(Random.Next(), _maxConnectionsPerHosts);
             _logicalEndpoint = g.LogicalEndPoint;
             if (g.LogicalEndPoint != null && g.PhusicalEndPoint == null)
             {
                 connection = await GetConnection(g.LogicalEndPoint, _randomKey);
             }
             else if (g.LogicalEndPoint != null && g.PhusicalEndPoint != null)
             {
                 connection = await GetConnection(g.LogicalEndPoint, g.PhusicalEndPoint, _randomKey);
             }
             else
             {
                 connection = await GetConnection(g.LogicalEndPoint, _randomKey);
             }
             Sender.Tell(new AskResponse(connection));
         }
         catch (Exception e)
         {
             Sender.Tell(new AskResponse(PulsarClientException.Unwrap(e)));
         }
     });
     Receive <CleanupConnection>(c =>
     {
         CleanupConnection(c.Address, c.ConnectionKey);
     });
     Receive <CloseAllConnections>(_ =>
     {
         CloseAllConnections();
     });
     Receive <ReleaseConnection>(c =>
     {
         ReleaseConnection(c.ClientCnx);
     });
     Receive <GetPoolSize>(c =>
     {
         Sender.Tell(new GetPoolSizeResponse(PoolSize));
     });
     Stash?.UnstashAll();
 }
예제 #6
0
        private async ValueTask GrabCnx()
        {
            if (_clientCnx != null)
            {
                _log.Warning($"[{_state.Topic}] [{_state.HandlerName}] Client cnx already set, ignoring reconnection request");
                Sender.Tell(new AskResponse(ConnectionAlreadySet.Instance));
                return;
            }

            if (!ValidStateForReconnection)
            {
                // Ignore connection closed when we are shutting down
                _log.Info($"[{_state.Topic}] [{_state.HandlerName}] Ignoring reconnection request (state: {_state.ConnectionState})");
                _sender.Tell(new AskResponse(PulsarClientException.Unwrap(new Exception("Invalid State For Reconnection"))));
            }
            await LookupConnection();
        }
예제 #7
0
        /// <summary>
        /// calls broker binaryProto-lookup api to get metadata of partitioned-topic.
        ///
        /// </summary>
        private async ValueTask GetPartitionedTopicMetadata(TopicName topicName, TimeSpan opTimeout)
        {
            var request     = Commands.NewPartitionMetadataRequest(topicName.ToString(), _requestId);
            var payload     = new Payload(request, _requestId, "NewPartitionMetadataRequest");
            var askResponse = await _clientCnx.Ask <AskResponse>(payload);

            if (askResponse.Failed)
            {
                var e                  = askResponse.Exception;
                var nextDelay          = Math.Min(_getPartitionedTopicMetadataBackOff.Next(), opTimeout.TotalMilliseconds);
                var reply              = _replyTo;
                var isLookupThrottling = !PulsarClientException.IsRetriableError(e) || e is PulsarClientException.TooManyRequestsException || e is PulsarClientException.AuthenticationException;
                if (nextDelay <= 0 || isLookupThrottling)
                {
                    reply.Tell(new AskResponse(new PulsarClientException.InvalidConfigurationException(e)));
                    _log.Error(e.ToString());
                    _getPartitionedTopicMetadataBackOff = null;
                }
                else
                {
                    _log.Warning($"[topic: {topicName}] Could not get connection while getPartitionedTopicMetadata -- Will try again in {nextDelay} ms: {e.Message}");
                    opTimeout.Subtract(TimeSpan.FromMilliseconds(nextDelay));
                    var id = await _generator.Ask <NewRequestIdResponse>(NewRequestId.Instance);

                    _requestId = id.Id;
                    await GetPartitionedTopicMetadata(topicName, opTimeout);
                }
            }

            var data = askResponse.ConvertTo <LookupDataResult>();

            if (data?.Error != ServerError.UnknownError)
            {
                _log.Warning($"[{topicName}] failed to get Partitioned metadata : {data.Error}:{data.ErrorMessage}");
                _replyTo.Tell(new AskResponse(new PartitionedTopicMetadata(0)));
            }
            else
            {
                _replyTo.Tell(new AskResponse(new PartitionedTopicMetadata(data.Partitions)));
            }
            _getPartitionedTopicMetadataBackOff = null;
        }
예제 #8
0
 public ConnectionFailed(PulsarClientException exception)
 {
     Exception = exception;
 }
예제 #9
0
 public ClientExceptions(PulsarClientException exception)
 {
     Exception = exception;
 }
예제 #10
0
        private void Awaiting()
        {
            Receive <SetClient>(c =>
            {
                //_pulsarClient = c.Client;
            });
            Receive <UpdateServiceUrl>(u =>
            {
                UpdateServiceUrl(u.ServiceUrl);
            });
            ReceiveAsync <GetBroker>(async b =>
            {
                try
                {
                    _replyTo = Sender;
                    await GetCnxAndRequestId();
                    await GetBroker(b);
                }
                catch (Exception e)
                {
                    _replyTo.Tell(new AskResponse(PulsarClientException.Unwrap(e)));
                }
            });
            ReceiveAsync <GetPartitionedTopicMetadata>(async p =>
            {
                try
                {
                    var opTimeout = _operationTimeout;
                    _replyTo      = Sender;
                    _getPartitionedTopicMetadataBackOff = (new BackoffBuilder()).SetInitialTime(TimeSpan.FromMilliseconds(100)).SetMandatoryStop(opTimeout.Multiply(2)).SetMax(TimeSpan.FromMinutes(1)).Create();

                    await GetCnxAndRequestId();
                    await GetPartitionedTopicMetadata(p.TopicName, opTimeout);
                }
                catch (Exception e)
                {
                    _replyTo.Tell(new AskResponse(PulsarClientException.Unwrap(e)));
                }
            });
            ReceiveAsync <GetSchema>(async s =>
            {
                try
                {
                    _replyTo = Sender;
                    await GetCnxAndRequestId();
                    await GetSchema(s.TopicName, s.Version);
                }
                catch (Exception e)
                {
                    _replyTo.Tell(new AskResponse(PulsarClientException.Unwrap(e)));
                }
            });

            ReceiveAsync <GetTopicsUnderNamespace>(async t =>
            {
                try
                {
                    var opTimeout = _operationTimeout;
                    _getTopicsUnderNamespaceBackOff = new BackoffBuilder().SetInitialTime(TimeSpan.FromMilliseconds(100)).SetMandatoryStop(opTimeout.Multiply(2)).SetMax(TimeSpan.FromMinutes(1)).Create();
                    _replyTo = Sender;
                    await GetCnxAndRequestId();
                    await GetTopicsUnderNamespace(t.Namespace, t.Mode, opTimeout);
                }
                catch (Exception e)
                {
                    _replyTo.Tell(new AskResponse(PulsarClientException.Unwrap(e)));
                }
            });
        }
예제 #11
0
 public AckError(long requestid, PulsarClientException exception)
 {
     RequestId = requestid;
     Exception = exception;
 }