Search in sources :

Example 1 with MessageFetcher

use of co.cask.cdap.messaging.MessageFetcher in project cdap by caskdata.

the class MessagingNotificationService method subscribe.

@Override
public <N> Cancellable subscribe(NotificationFeedId feed, NotificationHandler<N> handler, Executor executor) throws NotificationFeedNotFoundException, NotificationFeedException {
    Cancellable subscribeCancellable = super.subscribe(feed, handler, executor);
    // If already has a thread fetching, just return the cancellable.
    if (!needFetch.compareAndSet(false, true)) {
        return subscribeCancellable;
    }
    // Start fetching
    subscribeExecutor.execute(new Runnable() {

        private final long startTime = System.currentTimeMillis();

        private final RetryStrategy scheduleStrategy = RetryStrategies.exponentialDelay(100, 3000, TimeUnit.MILLISECONDS);

        private byte[] messageId;

        private int emptyFetchCount;

        @Override
        public void run() {
            try {
                MessageFetcher fetcher = messagingService.prepareFetch(notificationTopic);
                if (messageId == null) {
                    fetcher.setStartTime(startTime);
                } else {
                    fetcher.setStartMessage(messageId, false);
                }
                emptyFetchCount++;
                try (CloseableIterator<RawMessage> iterator = fetcher.fetch()) {
                    while (iterator.hasNext()) {
                        emptyFetchCount = 0;
                        RawMessage rawMessage = iterator.next();
                        NotificationMessage message = GSON.fromJson(new String(rawMessage.getPayload(), StandardCharsets.UTF_8), NotificationMessage.class);
                        try {
                            LOG.trace("Decoded notification: {}", message);
                            notificationReceived(message.getFeedId(), message.getNotificationJson());
                        } catch (Throwable t) {
                            LOG.warn("Error while processing notification {} with handler {}", message, t);
                        }
                        messageId = rawMessage.getId();
                    }
                }
            } catch (Exception e) {
                LOG.error("Failed to get notification", e);
            }
            // Back-off if it was empty fetch.
            if (emptyFetchCount > 0) {
                // Schedule the next fetch. Exponential strategy doesn't use the time component,
                // so doesn't matter what we passed in
                subscribeExecutor.schedule(this, scheduleStrategy.nextRetry(emptyFetchCount, startTime), TimeUnit.MILLISECONDS);
            } else {
                subscribeExecutor.execute(this);
            }
        }
    });
    return subscribeCancellable;
}
Also used : MessageFetcher(co.cask.cdap.messaging.MessageFetcher) CloseableIterator(co.cask.cdap.api.dataset.lib.CloseableIterator) Cancellable(org.apache.twill.common.Cancellable) NotificationFeedNotFoundException(co.cask.cdap.notifications.feeds.NotificationFeedNotFoundException) NotificationException(co.cask.cdap.notifications.service.NotificationException) NotificationFeedException(co.cask.cdap.notifications.feeds.NotificationFeedException) RawMessage(co.cask.cdap.messaging.data.RawMessage) RetryStrategy(co.cask.cdap.common.service.RetryStrategy)

Example 2 with MessageFetcher

use of co.cask.cdap.messaging.MessageFetcher in project cdap by caskdata.

the class FetchHandler method fetchMessages.

/**
 * Creates a {@link CloseableIterator} of {@link RawMessage} based on the given fetch request.
 */
private CloseableIterator<RawMessage> fetchMessages(GenericRecord fetchRequest, TopicId topicId) throws IOException, TopicNotFoundException {
    MessageFetcher fetcher = messagingService.prepareFetch(topicId);
    Object startFrom = fetchRequest.get("startFrom");
    if (startFrom != null) {
        if (startFrom instanceof ByteBuffer) {
            // start message id is specified
            fetcher.setStartMessage(Bytes.toBytes((ByteBuffer) startFrom), (Boolean) fetchRequest.get("inclusive"));
        } else if (startFrom instanceof Long) {
            // start by timestamp is specified
            fetcher.setStartTime((Long) startFrom);
        } else {
            // This shouldn't happen as it's guaranteed by the schema
            LOG.warn("Ignore unrecognized type for startFrom. Type={}, Value={}", startFrom.getClass(), startFrom);
        }
    }
    Integer limit = (Integer) fetchRequest.get("limit");
    if (limit != null) {
        fetcher.setLimit(limit);
    }
    ByteBuffer encodedTx = (ByteBuffer) fetchRequest.get("transaction");
    if (encodedTx != null) {
        fetcher.setTransaction(TRANSACTION_CODEC.decode(ByteBuffers.getByteArray(encodedTx)));
    }
    return fetcher.fetch();
}
Also used : MessageFetcher(co.cask.cdap.messaging.MessageFetcher) ByteBuffer(java.nio.ByteBuffer)

Aggregations

MessageFetcher (co.cask.cdap.messaging.MessageFetcher)2 CloseableIterator (co.cask.cdap.api.dataset.lib.CloseableIterator)1 RetryStrategy (co.cask.cdap.common.service.RetryStrategy)1 RawMessage (co.cask.cdap.messaging.data.RawMessage)1 NotificationFeedException (co.cask.cdap.notifications.feeds.NotificationFeedException)1 NotificationFeedNotFoundException (co.cask.cdap.notifications.feeds.NotificationFeedNotFoundException)1 NotificationException (co.cask.cdap.notifications.service.NotificationException)1 ByteBuffer (java.nio.ByteBuffer)1 Cancellable (org.apache.twill.common.Cancellable)1