GitHub - aojet/Aojet: An actor model library for swift. (original) (raw)
Aojet
Aojet is an actor model implemetion for swift.
Features
- Asynchronous, non-blocking and highly performant message-driven programming model
- Safe as well as efficient messaging
- Message ordering using Local Synchronization Constraints
- Fair scheduling
- Modular and extensible
- A promise implementation for general usage
- Portable(Support iOS and Mac platform currently)
Requirements
- Swift 3.0
- iOS 8.0+ or macOS 10.10+
Installation
Aojet is available through Carthage. Add this line to your Cartfile
Usage
Make an Actor
This is a simple actor implementation:
class SomeActor: Actor { override func onReceive(message: Any) throws { switch message { case let m as DoSomething: doSomething(object: m.object) default: try super.onReceive(message: message) } }
func doSomething(object: Any) { //This should run on the actor thread. print(Thread.current) print("Do something with object: (object)") //Do something }
struct DoSomething { let object: Any }
}
Create ActorRef
let actorSystem = ActorSystem.system actorSystem.traceInterface = ActorTrace() //For internal logging let actor = try actorSystem.actorOf(path: "testActor", creator: AnyActorCreator{ () -> Actor in return SomeActor() })
Send Message to ActorRef
actor.send(message: SomeActor.DoSomething(object: "An object")) //Success actor.send(message: "An string") //Drop actor.send(message: SomeActor.DoSomething(object: "Another object")) //Success
Make an AskableActor
class SomeActor: AskableActor {
override func onAsk(message: Any) throws -> Promise? { switch message { case let m as AskSomething: return askSomething(object: m.object) default: let p = try super.onAsk(message: message) print("Promise: (p)") return p } }
override func onReceive(message: Any) throws { switch message { case let m as DoSomething: doSomething(object: m.object) default: try super.onReceive(message: message) } }
func doSomething(object: Any) { //This should run on the actor thread. print(Thread.current) print("Do something with object: (object)") //Do something }
func askSomething(object: Any) -> Promise { //This should run on the actor thread. print(Thread.current) print("Ask something with object: (object)")
return Promise(value: "A response")
}
struct DoSomething { let object: Any }
struct AskSomething { let object: Any } }
Make an Ask Request
let p1: Promise = actor.ask(message: SomeActor.AskSomething(object: "An object for ask")) p1.then { (res) in print("Ask response:(res)") }.failure { (error) in print("Ask error:(error)") }
Promise Usage
There are some ways to create a promise:
//Define an error for test enum TestError: Error { case general(message: String) }
//Immediate Promise let p1 = Promise(value: 1) let p2 = Promise(error: TestError.general(message: "Test error."))
//Async Promise let p3 = Promise { (resolver) in let url = URL(string: "https://api.ipify.org") let task = URLSession.shared.dataTask(with: url!) {(data, response, error) in if error != nil { resolver.error(error!) } else if data != nil { let s = String(bytes: data!, encoding: String.Encoding.utf8) print(s) resolver.result(s) } else { resolver.result(nil) } } task.resume() }