示例#1
0
  @Override
  public void onReconnected() {
    log.info("reconnected");
    if (mode.contains(MODE.RESEND_SUBSCRIBE_ON_RECONNECTED)) {

      Set<String> channels;

      // channel as sourceDispatcherId
      channels = new HashSet<String>();
      channels.add(getSourceDispatcherId());
      driverImpl.subscribeChannels(channels);

      // channels as object_IDs registered with localObjectsMap
      channels = localObjectsMap.keySet();
      if (!channels.isEmpty()) {
        driverImpl.subscribeChannels(channels);
      }

      // all channels registered with subscribersMap
      channels = subscribersMap.getSubscribedChannels();
      if (!channels.isEmpty()) {
        driverImpl.subscribeChannels(channels);
      }

      // re-SUBSCRIBE completed with all the registered channels.
      pubSubDriverSuspended = false; // Resumed
    } else {
      // You may add some code here to inform other objects that
      // the network connectivity has resumed or the pubsub server
      // has become available.
    }
  }
示例#2
0
 /**
  * Closes the services.
  *
  * <p>You can also do "try-with-resources" to automatically close this class.
  */
 public void close() {
   // TODO: Graceful termination of all the components and the transport
   // TODO: subscriptionFeeder termination
   driverImpl.close();
   remoteTransactions.onFinalize();
   subscribersMap.clear();
   log.info("terminated");
 }
示例#3
0
 /**
  * Channel unsubscription service.
  *
  * @param subscriberId subscriber's object ID
  * @param channelsToBeUnsubscribed channels to be unsubscribed
  */
 public void unsubscribeChannels(
     final String subscriberId, final Map<String, Set<String>> channelsToBeUnsubscribed) {
   Set<String> channels = new HashSet<>();
   for (String publisherId : channelsToBeUnsubscribed.keySet()) {
     Set<String> eventIds = channelsToBeUnsubscribed.get(publisherId);
     for (String eventId : eventIds) {
       String channel = channelString(publisherId, eventId);
       if (subscribersMap.removeSubscription(channel, subscriberId)) {
         channels.add(channel);
       }
     }
   }
   if (!channels.isEmpty() && !pubSubDriverSuspended) {
     driverImpl.unsubscribeChannels(channels);
   }
 }
示例#4
0
  /**
   * onMessage implementation.
   *
   * <p>This method has two roles:
   *
   * <ul>
   *   <li>Works like a mail transfer agent to transfer a received request or event to {@link
   *       org.o3project.odenos.remoteobject.RemoteObject}.
   *   <li>Supports both synchronous and asynchronous messaging.
   * </ul>
   */
  @Override
  public void onMessage(final String channel, byte[] message) {

    serial++; // Serial number for incoming messages.

    try {
      BufferUnpacker upk = msgpack.createBufferUnpacker(message);
      // read delivery header.
      byte type = upk.readByte();
      final int sno = upk.readInt(); // Sequence number for outgoing request messages.
      final String sourceObjectId = upk.readString(); // i.e., channel

      RemoteObject localObject = null;
      Queue<Mail> mailbox = null;
      Mail mail = null;

      switch (type) {
        case TYPE_REQUEST: // Transaction(request): synchronous operation
          /*
           *  --- request --> dispatchRequest() -------> [RemoteObject]
           *                                                  |
           *  <-- response --- publishResponseAsync() <-------+
           */
          final Request request = upk.read(Request.class);
          if (log.isDebugEnabled()) {
            log.debug(
                "Request received:\n"
                    + "  MessageDispatcher: {}\n"
                    + "  sno: {}\n"
                    + "  channel: {}\n"
                    + "  method: {}\n"
                    + "  objectId: {}\n"
                    + "  sourceObjectId: {}\n"
                    + "  path: /{}/\n"
                    + "  body: {}",
                sourceDispatcherId,
                sno,
                channel,
                request.method,
                request.objectId,
                sourceObjectId,
                request.path,
                request.getBodyValue());
          }

          // Wraps the request with Mail and deliver it to a mailbox.
          String to = request.objectId;
          mail = new Mail(serial, sno, to, sourceObjectId, this, request, null);
          localObject = localObjectsMap.get(to);
          if (localObject != null) {
            mailbox = localObject.getMailbox();
            synchronized (mailbox) {
              mailbox.add(mail);
              if (!localObject.isRunning()) {
                localObject.setRunning(true);
                // Assigns a thread to read a mail in the mailbox.
                actor.read(localObject);
              }
            }
          }
          break;

        case TYPE_RESPONSE: // Transaction(response): synchronous operation
          /*
           *                                 publishRequestAsync()
           * requestSync() -> [RemoteTransaction] ---- request -----> [RemoteObject]
           *              <--            ^                                  |
           *                             |                     publishResponseAsync()
           *                             |                                  |
           *                             +- signalResponse() <-- response --+
           */
          Response response = upk.read(Response.class);
          if (log.isDebugEnabled()) {
            log.debug(
                "Response received:\n"
                    + "  MessageDispatcher: {}\n"
                    + "  channel: {}\n"
                    + "  statusCode: {}\n"
                    + "  body: {}",
                sourceDispatcherId,
                channel,
                response.statusCode,
                response.getBodyValue());
          }
          remoteTransactions.signalResponse(sno, response);
          break;

        case TYPE_EVENT: // Asynchronous
          /*
           * publishEventAsync() -- event --> dispatchEvent() --> [RemoteObject]
           *                                         :
           *                              [EventSubscriptionMap]
           */
          final Event event = upk.read(Event.class);
          if (log.isDebugEnabled()) {
            log.debug(
                "Event received:\n"
                    + "  MessageDispatcher: {}\n"
                    + "  channel: {}\n"
                    + "  body: {}",
                sourceDispatcherId,
                channel,
                event.getBodyValue());
          }

          // All the subscribers of the channel
          final Collection<String> subscribers = subscribersMap.getSubscribers(channel);
          if (subscribers == null) { // No subscribers found on the channel
            if (log.isDebugEnabled()) {
              log.debug("no subscribers subscribing the channel: {}", channel);
            }
            return; // Silently discards the event
          }

          // Wraps the event with Mail and deliver it to a mailbox.
          for (String subscriber : subscribers) {
            localObject = localObjectsMap.get(subscriber);
            if (localObject != null) {
              mail = new Mail(serial, sno, subscriber, channel, this, null, event);
              mailbox = localObject.getMailbox();
              synchronized (mailbox) {
                mailbox.add(mail);
                if (!localObject.isRunning()) {
                  localObject.setRunning(true);
                  // Assigns a thread to read a mail in the mailbox.
                  actor.read(localObject);
                }
              }
            }
          }
          break;

        default:
          break;
      }
    } catch (Exception e) {
      log.error("onMessage failed", e);
    }
  }