All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ecfront.ez.framework.service.eventbus.EventBusProcessor.scala Maven / Gradle / Ivy

package com.ecfront.ez.framework.service.eventbus

import com.ecfront.common.{JsonHelper, Resp}
import com.ecfront.ez.framework.core.EZContext
import com.typesafe.scalalogging.slf4j.LazyLogging
import io.vertx.core._
import io.vertx.core.eventbus.{DeliveryOptions, EventBus, Message, MessageConsumer}
import io.vertx.spi.cluster.hazelcast.HazelcastClusterManager

import scala.collection.mutable.ArrayBuffer
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, Future, Promise}

/**
  * 事件总线处理器
  */
object EventBusProcessor extends LazyLogging {

  private var eb: EventBus = _

  private val consumerEBs = ArrayBuffer[MessageConsumer[_]]()

  def init(vertx: Vertx): Resp[String] = {
    Await.result(Async.init(vertx), Duration.Inf)
  }

  def publish(address: String, message: Any): Unit = {
    Async.publish(address, message)

  }

  def send(address: String, message: Any, timeout: Long = 30 * 1000): Unit = {
    Async.send(address, message, timeout)
  }

  def sendWithReply[E: Manifest](address: String, message: Any, timeout: Long = 30 * 1000): (E, Any => Unit) = {
    Await.result(Async.sendWithReply(address, message, timeout), Duration.Inf)
  }

  def consumer[E: Manifest](address: String): (E, Any => Unit) = {
    Await.result(Async.consumer(address), Duration.Inf)
  }

  object Async {

    def init(vertx: Vertx): Future[Resp[String]] = {
      val p = Promise[Resp[String]]()
      val mgr = new HazelcastClusterManager()
      val options = new VertxOptions().setClusterManager(mgr)
      Vertx.clusteredVertx(options, new Handler[AsyncResult[Vertx]] {
        override def handle(res: AsyncResult[Vertx]): Unit = {
          if (res.succeeded()) {
            eb = res.result().eventBus()
            logger.info("EventBus init successful.")
            p.success(Resp.success(null))
          } else {
            logger.error("EventBus init error.", res.cause())
            p.success(Resp.serverError(res.cause().getMessage))
          }
        }
      })
      sys.addShutdownHook {
        consumerEBs.foreach {
          _.unregister()
        }
      }
      p.future
    }

    def publish(address: String, message: Any): Unit = {
      eb.publish(address, JsonHelper.toJsonString(message))
    }

    def send(address: String, message: Any, timeout: Long = 30 * 1000): Unit = {
      sendAdv[Void](address, message, null, timeout)
    }

    def sendWithReply[E: Manifest](address: String, message: Any, timeout: Long = 30 * 1000): Future[(E, Any => Unit)] = {
      val p = Promise[(E, Any => Unit)]()
      sendAdv[E](address, message, {
        (message, reply) =>
          p.success((message, reply))
      }, timeout)
      p.future
    }

    def sendAdv[E: Manifest](address: String, message: Any, callback: (E, Any => Unit) => Unit, timeout: Long = 30 * 1000): Unit = {
      if (callback != null) {
        val opt = new DeliveryOptions()
        opt.setSendTimeout(timeout)
        eb.send(address, JsonHelper.toJsonString(message), opt, new Handler[AsyncResult[Message[String]]] {
          override def handle(event: AsyncResult[Message[String]]): Unit = {
            if (event.succeeded()) {
              logger.trace(s"Received a reply [$address] : ${event.result.body()} ")
              val message = JsonHelper.toObject[E](event.result().body())
              if (callback != null) {
                EZContext.vertx.executeBlocking(new Handler[io.vertx.core.Future[Void]] {
                  override def handle(e: io.vertx.core.Future[Void]): Unit = {
                    try {
                      callback(message, {
                        reply =>
                          val replyMessage = JsonHelper.toJsonString(reply)
                          logger.trace(s"Reply a message [$address] : $replyMessage ")
                          event.result.reply(replyMessage)
                      })
                      e.complete()
                    } catch {
                      case ex: Throwable =>
                        logger.error("EventBus execute error.", ex)
                        e.fail(ex)
                    }
                  }
                }, false, new Handler[AsyncResult[Void]] {
                  override def handle(event: AsyncResult[Void]): Unit = {
                  }
                })
              }
            } else {
              logger.error(s"Receive reply [$address] error.", event.cause())
            }
          }
        })
      } else {
        eb.send(address, JsonHelper.toJsonString(message))
      }
    }

    def consumer[E: Manifest](address: String): Future[(E, Any => Unit)] = {
      val p = Promise[(E, Any => Unit)]()
      consumerAdv[E](address, {
        (message, reply) =>
          p.success((message, reply))
      })
      p.future
    }

    def consumerAdv[E: Manifest](address: String, callback: (E, Any => Unit) => Unit): Unit = {
      val consumerEB = eb.consumer(address, new Handler[Message[String]] {
        override def handle(event: Message[String]): Unit = {
          logger.trace(s"Received a message [$address] : ${event.body()} ")
          val message = JsonHelper.toObject[E](event.body())
          EZContext.vertx.executeBlocking(new Handler[io.vertx.core.Future[Void]] {
            override def handle(e: io.vertx.core.Future[Void]): Unit = {
              try {
                callback(message, {
                  reply =>
                    val replyMessage = JsonHelper.toJsonString(reply)
                    logger.trace(s"Reply a message [$address] : $replyMessage ")
                    event.reply(replyMessage)
                })
                e.complete()
              } catch {
                case ex: Throwable =>
                  logger.error("EventBus execute error.", ex)
                  e.fail(ex)
              }
            }
          }, false, new Handler[AsyncResult[Void]] {
            override def handle(event: AsyncResult[Void]): Unit = {
            }
          })
        }
      })
      consumerEB.completionHandler(new Handler[AsyncResult[Void]] {
        override def handle(event: AsyncResult[Void]): Unit = {
          if (event.succeeded()) {
            consumerEBs += consumerEB
          } else {
            logger.error(s"Register consumer [$address] error.", event.cause())
          }
        }
      })
      consumerEB.exceptionHandler(new Handler[Throwable] {
        override def handle(event: Throwable): Unit = {
          logger.error(s"Process consumer [$address] error.", event)
        }
      })
    }

  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy