All Projects → simerplaha → Actor

simerplaha / Actor

Licence: apache-2.0
A type-safe Actor class and WiredActor for sending functions as messages

Programming Languages

scala
5932 projects

Projects that are alternatives of or similar to Actor

dotfiles
My dotfiles
Stars: ✭ 16 (+0%)
Mutual labels:  functions
Nuclio
High-Performance Serverless event and data processing platform
Stars: ✭ 4,213 (+26231.25%)
Mutual labels:  functions
Openwhisk
Apache OpenWhisk is an open source serverless cloud platform
Stars: ✭ 5,499 (+34268.75%)
Mutual labels:  functions
Unparam
Find unused parameters in Go
Stars: ✭ 311 (+1843.75%)
Mutual labels:  functions
Coobjc
coobjc provides coroutine support for Objective-C and Swift. We added await method、generator and actor model like C#、Javascript and Kotlin. For convenience, we added coroutine categories for some Foundation and UIKit API in cokit framework like NSFileManager, JSON, NSData, UIImage etc. We also add tuple support in coobjc.
Stars: ✭ 3,921 (+24406.25%)
Mutual labels:  actor
Microcule
SDK and CLI for spawning streaming stateless HTTP microservices in multiple programming languages
Stars: ✭ 454 (+2737.5%)
Mutual labels:  functions
invokable
Objects are functions! Treat any Object or Class as a Proc (like Enumerable but for Procs).
Stars: ✭ 40 (+150%)
Mutual labels:  functions
Fission
Fast and Simple Serverless Functions for Kubernetes
Stars: ✭ 6,646 (+41437.5%)
Mutual labels:  functions
Akka.net
Port of Akka actors for .NET
Stars: ✭ 4,024 (+25050%)
Mutual labels:  actor
Hibernate Springboot
Collection of best practices for Java persistence performance in Spring Boot applications
Stars: ✭ 589 (+3581.25%)
Mutual labels:  functions
Pandasvault
Advanced Pandas Vault — Utilities, Functions and Snippets (by @firmai).
Stars: ✭ 316 (+1875%)
Mutual labels:  functions
Qpc
QP/C real-time embedded framework/RTOS for embedded systems based on active objects (actors) and hierarchical state machines
Stars: ✭ 379 (+2268.75%)
Mutual labels:  actor
Dispatch
Dispatch is a framework for deploying and managing serverless style applications.
Stars: ✭ 529 (+3206.25%)
Mutual labels:  functions
js-utils
A collection of dependency-free JavaScript utilities 🔧
Stars: ✭ 22 (+37.5%)
Mutual labels:  functions
Ray
项目停止更新,新项目:https://github.com/RayTale/Vertex
Stars: ✭ 635 (+3868.75%)
Mutual labels:  actor
unity-gameplay-framework
A gameplay framework to simplify Unity development.
Stars: ✭ 30 (+87.5%)
Mutual labels:  actor
Et
Unity3D Client And C# Server Framework
Stars: ✭ 5,138 (+32012.5%)
Mutual labels:  actor
Actix
Actor framework for Rust.
Stars: ✭ 6,764 (+42175%)
Mutual labels:  actor
Qbit
The Java microservice lib. QBit is a reactive programming lib for building microservices - JSON, HTTP, WebSocket, and REST. QBit uses reactive programming to build elastic REST, and WebSockets based cloud friendly, web services. SOA evolved for mobile and cloud. ServiceDiscovery, Health, reactive StatService, events, Java idiomatic reactive programming for Microservices.
Stars: ✭ 702 (+4287.5%)
Mutual labels:  actor
Reattempt
🤞 Give your functions another chance
Stars: ✭ 570 (+3462.5%)
Mutual labels:  functions

Please use swaydb's Actor implementation instead which includes caching, recovery & ordered queues. It's easier to maintain and add features to it within SwayDB's repo as I'm using it constantly there.

libraryDependencies += "io.swaydb" %% "data" % "latest"

The Actor will be moved to it's own repo since it's not dependant on the database.

Actor

Actor - A small type-safe class that implements most commonly used Actor APIs including ask (?) which returns a typed Future[R].

WiredActor - Invoke functions directly on Actors. Send functions as messages.

Setup

libraryDependencies += "com.github.simerplaha" %% "actor" % "0.3"

Make sure to import ExecutionContext

import scala.concurrent.ExecutionContext.Implicits.global

WiredActor

Functions can be sent, invoked & scheduled as messages to WiredActors similar to messages in an Actor.

WiredActors can be created on any class instance or object.

Create a WiredActor

//your class that contains Actor functions
object MyImpl {
  def hello(name: String): String =
    s"Hello $name"

  def helloFuture(name: String): Future[String] =
    Future(s"Hello $name from the Future!") //some future operation
}

//create WiredActor
val actor = Actor.wire(MyImpl)

ask

//invoke function
val response: Future[String] = actor.ask(_.hello("World"))
response.foreach(println)

askFlatMap

val responseFlatMap: Future[String] = actor.askFlatMap(_.helloFuture("World"))
responseFlatMap.foreach(println)

send

val unitResponse: Unit = actor.send(_.hello("World again!"))

schedule

//schedule a function call on the actor. Returns Future response and TimerTask to cancel.
val scheduleResponse: (Future[String], TimerTask) = actor.scheduleAsk(delay = 1.second)(_.hello("World"))
scheduleResponse._1.foreach(println)

PingPong example using WiredActor

import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global

object WiredPingPongDemo extends App {

  class WiredPingPong(var pingCount: Int, var pongCount: Int) {
    def ping(replyTo: WiredActor[WiredPingPong]): Unit = {
      pingCount += 1
      println(s"pingCount: $pingCount")
      replyTo.send(_.pong(replyTo))
    }

    def pong(replyTo: WiredActor[WiredPingPong]): Unit = {
      pongCount += 1
      println(s"pongCount: $pongCount")
      replyTo.send(_.ping(replyTo))
    }
  }

  Actor
    .wire(new WiredPingPong(0, 0))
    .send {
      (impl, self) =>
        impl.ping(self)
    }

  Thread.sleep(1.seconds.toMillis)
}

See WiredPingPongStateless for a stateless version of the above WiredPingPong WiredActor.

Actor

Stateless Actor

val actor =
  Actor[Int](
    (message, self) =>
      println(message)
  )

actor ! 1

Stateful Actor

case class State(var counter: Int)

val actor =
  Actor[Int, State](State(0))(
    (message, self) =>
      self.state.counter += 1
  )

Timer actor

A timer actor will process messages in batches after the set delays. Similar to above a stateful timer Actor can also be created.

import scala.concurrent.duration._

//stateless timer actor
val actor =
  Actor.timer[Int](delays = 1.second) {
    (message, self) =>
    //do something
  }

Scheduling messages to self

self.schedule returns a java TimerTask which is cancellable.

val actor =
  Actor[Int](
    (message, self) =>
      self.schedule(message = 1, delay = 1.second)  
  )

Terminating an Actor

val actor =
  Actor[Int](
    (message, self) =>
      println(message)
  )

actor.terminate()
//cannot send messages to a terminated actor.
(actor ! 1) shouldBe Left(Result.TerminatedActor)

Ask - Get a Future response

case class CreateUser(name: String)(val replyTo: ActorRef[Boolean])

val actor = Actor[CreateUser] {
  (message: CreateUser, _) =>
    message.replyTo ! true
}

val response: Future[Boolean] = (actor ? CreateUser("Tony Stark")).right.get

Await.result(response, 1.second)

Terminating an Actor on message failure

By default actors are not terminated if there is a failure processing a message. The following actor enables termination if there is a failure processing a message.

val actor =
  Actor[Int](
    (message, self) =>
      throw new Exception("Kaboom!")
  ).terminateOnException() //enable terminate on exception

(actor ! 1) shouldBe Right(Result.Sent) //first message sent is successful
eventually(actor.isTerminated() shouldBe true) //actor is terminated
(actor ! 2) shouldBe Left(Result.TerminatedActor) //cannot sent messages to a terminated actor

Testing

Borrowing ideas from Akka the TestActor implements APIs to test messages in an Actor's mailbox.

val actor = TestActor[Int]()

actor.expectNoMessage(after = 1.second) //expect a message after delay in the Actor's mailbox
val got = actor.getMessage() //fetch the first message in the actor's mailbox
actor.expectMessage[Int]() //expect a message of some type

PingPong example

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import com.github.simerplaha.actor._

case class Pong(replyTo: ActorRef[Ping])
case class Ping(replyTo: ActorRef[Pong])
case class State(var count: Int)

val ping =
  Actor[Ping, State](State(0)) {
    case (message, self) =>
      self.state.count += 1
      println(s"Ping: ${self.state.count}")
      message.replyTo ! Pong(self)
  }

val pong =
  Actor[Pong, State](State(0)) {
    case (message, self) =>
      self.state.count += 1
      println(s"Pong: ${self.state.count}")
      message.replyTo ! Ping(self)
  }

pong ! Pong(ping)

//run this for 1 seconds
Thread.sleep(1.second.toMillis)
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].