Skip to content

Latest commit

 

History

History
102 lines (92 loc) · 3.46 KB

README.md

File metadata and controls

102 lines (92 loc) · 3.46 KB

Asterisque*

Asterisque* is lightweight bidirectional RPC with asynchronous messaging framework, protocol and implementation for P2P distributed system.

Documents

Getting Started

To build asterisque* JAR library, you may clone asterisque* GitHub repository and build asterisk_2.10-0.1.jar by sbt package.

$ git clone https://github.com/torao/asterisk.git
$ cd asterisk
$ ./sbt package

Or, you can also run directory by using sbt run to specify following sample code of bi-directional RPC.

import com.kazzla.asterisk._
import java.net.InetSocketAddress
import scala.concurrent.{Await,Future,Promise}
import scala.concurrent.duration.Duration
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util._
// 1) Simple implementation is to define scala trait or java interface
// as IDL to agree interface statically between client and server.
// Those every methods must has @Export(function-id) annotation and
// `Future` return type.
trait Sample1 {
  @Export(10)
  def greeting(name:String):Future[String]
}
trait Sample2 {
  @Export(10)
  def surround(text:String):Future[String]
}
// 2) Implementation class of interfaces is used as remote service on
// server node. You may calculate result asynchronously after returning
// `Future` immediately.
class Sample1Impl extends Service with Sample1 {
  def greeting(name:String) = Session() match {
    case Some(session) =>
      val promise = Promise[String]()
      session.bind(classOf[Sample2]).surround(name).onComplete {
        case Success(str) => promise.success(s"hello, $str")
        case Failure(ex) => promise.failure(ex)
      }
      promise.future
    case None => Promise.failed(new Exception()).future
  }
}
class Sample2Impl extends Service with Sample2 {
  def surround(text:String) = Promise.successful(s"*$text*").future
}
object SampleImpl {
  def main(args:Array[String]):Unit = {
    // 3) Instantiate client and server nodes that use Netty as messenger bridge.
    val node1 = Node("node 1").serve(new Sample1Impl).bridge(netty.Netty).build()
    val node2 = Node("node 2").serve(new Sample2Impl).bridge(netty.Netty).build()
    def close() = Seq(node1,node2).foreach{ _.shutdown() }
    // 4) The server listen on port 9999 without any action on accept.
    node1.listen(new InetSocketAddress(9999))
    // 5) Client retrieve `Future[Session]` by connecting to server port 9999.
    val future = node2.connect(new InetSocketAddress(9999))
    val session = Await.result(future, Duration.Inf)
    // 6) Bind remote interfaces from client session.
    val sample = session.bind(classOf[Sample1])
    // 7) Call remote procedure and action asynchronously.
    sample.greeting("asterisk").onComplete {
      case Success(str) =>
        println(str)
        close()
      case Failure(ex) =>
        ex.printStackTrace()
        close()
    }
  }
}
$ ./sbt run
[info] Set current project to asterisk (in build file:/Users/torao/git/asterisk/)
[info] Compiling 1 Scala source to /Users/torao/git/asterisk/target/scala-2.10/classes...
[info] Running SampleImpl
hello, *asterisk*
[success] Total time: 11 s, completed 2014/02/03 5:53:31

License

All sources and related resources are available under Apache License Version 2.0.