How to migrate Input/OutputChannel from Scala Actors to Akka? - scala

According to this guide:
http://docs.scala-lang.org/overviews/core/actors-migration-guide.html
scala.actors._ -> akka.actor._
However there does not seeem to be InputChannel/OutputChannel/Channel.
So to migrate from Scala Actors to Akka Actors, where can I find those Channel APIs?

I think what you might want is contained in the latest version of Akka and is called Typed Channels. It's marked as experimental because its a new feature and will probably be in flux for a bit but I believe it's similar to what you are looking for.
http://doc.akka.io/docs/akka/2.2.0/scala/typed-channels.html

There is a SynapseGrid library that can be a replacement for typed channels between actors.
One can create a so called "Contact" that can be shared between actors.
In one actor (Subsystem) one passes data to the contact:
val someInput = contact[String]("someInput")
val SharedContact = contact[String]("SharedContact")
outputs(SharedContact)
someInput.map("Hello, "+_)>>SharedContact
In another actor it appears on the same contact ready for consumption:
inputs(SharedContact)
SharedContact.map(_+"!").foreach(s => println("Got from other actor: "+s))
Everything is strictly typed.
However, SynapseGrid is more suitable for large systems.

Related

Scala : Syntactic Sugar

I have been scratching my head to understand how to read this function:
private def greeterBehavior(currentGreeting: String): Behavior[Command] =
Actor.immutable[Command] { (ctx, msg) =>
msg match {
case WhoToGreet(who) =>
greeterBehavior(s"hello, $who")
case Greet =>
println(currentGreeting)
Actor.same
}
}
Questions:
1 ) function takes string and returns Behavior[Command] . ( understood)
But .. what is Actor.immutable[Command] ?
Is this a type casting ? or is it an object ?
2) if I have to understand such syntax what is the best place or book I can refer?
To address the comments regarding the location of the API documentation for Actor.immutable:
As the Akka documentation clearly states, the Akka Typed API is still in flux:
This module is currently marked as may change in the sense of being the subject of active research. This means that API or semantics can change without warning or deprecation period and it is not recommended to use this module in production just yet—you have been warned.
Apparently you're using a pre-2.5.10 version of Akka: the Actor object was removed from the Akka Typed module in version 2.5.10.
From Akka 2.5.2 to Akka 2.5.8, there was an akka.typed.scaladsl.Actor.immutable method.
In Akka 2.5.9, the Actor.immutable method moved to the akka.actor.typed package.
In Akka 2.5.10, the akka.actor.typed.Actor object was removed. This object is still absent in 2.5.11 and 2.5.12 (the current version of Akka at the time of this writing).
Here is the Scaladoc for the last version of Actor.immutable from Akka 2.5.9:
def immutable[T](onMessage: (ActorContext[T], T) => Behavior[T]): Immutable[T]
Construct an actor behavior that can react to both incoming messages and lifecycle signals. After spawning this actor from another actor (or as the guardian of an akka.actor.typed.ActorSystem) it will be executed within an ActorContext that allows access to the system, spawning and watching other actors, etc.
This constructor is called immutable because the behavior instance does not need and in fact should not use (close over) mutable variables, but instead return a potentially different behavior encapsulating any state changes.
immutable is a method on Actor, which takes in a generic type parameter, in this case that type is Command.
Any intro to Scala material worth reading should cover generics. "Programming in Scala" and "Scala for the Impatient" are both popular.

How do I create a "Locator" for Akka Actors

I am an akka newbie and I'm trying to build an application that is composed of Spray and Akka. As part of the application I would like to give my fellow developers (who are also new to akka) some prepackaged actors that do specific things which they can then "attach" to their actor systems.
Specifically :
Is there a recommended way to provide a "actor locator"/"Actor System locator" -- think service locator like API to lookup and send messages to actors ? In other words How can I implement a function like:
ActorLocator.GoogleLocationAPIActor
so that I can then use it like :
ActorLocator.GoogleLocationAPIActor ! "StreetAddress"
Assume that getGoogleLocationAPIActor returns an ActorRef that accepts Strings that are addresses and makes an HTTP call to google to resolve that to a lat/lon.
I could internally use actorSelection, but :
I would like to provide the GoogleLocationAPIActor as part of a library that my fellow developers can use
#1 means that when my fellow developer builds an actor based application, he needs a way to tell the library code where the actor system is, so that the library can go an attach the actor to it (In keeping with the one actor system per application practice). Of course in a distributed environment, this could be a guardian for a cluster of actors that are running remotely.
Currently I define the ActorSystem in an object like and access it everywhere like
object MyStage{
val system:ActorSystem = ActorSystem("my-stage")
}
then
object ActorLocator{
val GoogleLocationAPIActor = MyStage.system.actorOf(Props[GoogleLocationAPI])
}
This approach seems to be similar to this but I'm not very sure if this is a good thing. My concerns are that the system seems too open for anyone to add children to without any supervision hierarchy, it seems a bit ugly.
Is my ask a reasonable one or Am I thinking about this wrong ?
How can we have "build up" a library of actors that we can reuse across apps ?
Since this is is about designing an API, you're dangerously close to opinion territory but anyway, here is how I would be tempted to structure this. Personally I'm quite allergic to global singletons so:
Since ActorLocator is a service, I would organize it as a Trait:
trait ActorLocator {
def GoogleLocationAPIActor: ActorRef
def SomeOtherAPIActor: ActorRef
}
Then, you can have an implementation of the service such as:
class ActorLocatorLocalImpl(system: ActorSystem) extends ActorLocator {
override lazy val GoogleLocationAPIActor: ActorRef =
system.actorOf(Props[GoogleLocationAPI])
//etc
}
And a Factory object:
object ActorLocator {
def local(system: ActorSystem): ActorLocator =
new ActorLocatorLocalImpl(system)
}
If you need to create more complex implementations of the service and more complex factory methods, the users, having constructed a service, still just deal with the interface of the Trait.

Untyped vs TypedActors - why use untyped?

I am trying to understand why one would use untyped actors over typed actors.
I have read several posts on this, some of them below:
What is the difference between Typed and UnTyped Actors in Akka? When to use what?
http://letitcrash.com/post/19074284309/when-to-use-typedactors
I am interested in understanding why untyped actors are better in the context of:
a web server,
A distributed architecture
Scalability,
Interoperability with applications written in other programming
languages.
I am aware, that untyped actors are better in the context of FSM because of the become/unbecome functionality.
I can see the possibilities of untyped in a load balancer, as it does not have to be aware of the contents of the messages, but just forward them to other actors. However this could be implemented in a typedactor as well.
Can someone come up with a few use case in the areas mentioned above, where untyped actors are "better"?
There is a generic disadvantage for type actors: they are hard to extend. When you use normal traits you can easily combine them to build object that implements both interfaces
trait One {
def callOne(arg : String)
}
trait Two {
def callTwo(arg : Double)
}
trait Both extends One with Two
The Both trait supports two calls combined from two traits.
If you usage actor approach that process messages instead of making direct calls you is still capable with extending interfaces refusing type safety as price.
trait One {
val receiveOne : PartialFunction[String,Unit] = {
case msg : String => ()
}
}
trait Two {
val receiveTwo : PartialFunction[Double, Unit] = {
case msg : Double => ()
}
}
trait Both extends One with Two {
val receive : PartialFunction[Any, Unit] = receiveOne orElse receiveTwo
}
The receive value in Both trait combines two partial functions. The first accepts only Strings, the second - only Doubles. They have single common supertype: Any. So extended version should use Any as argument and becomes effectively untyped. The flaw is in scala type system that supports type multiplication using with keyword, but does not support union types. You could not define Double or String.
Typed actors lose ability for easy extension. Actors shifts type checks to contravariant position and extending it requires union types. You can see how they works in ceylon programming language.
It is not that untyped and typed actors have different sphere of application. All questioned functionality may be expressed in terms of both. The choice is more about methodology and convenience.
Typing allows you to avoid some errors before going to unit testing. It will cost boilerplate for auxiliary protocol declarations. In the example above you should declare union type explicitly:
trait Protocol
final case class First(message : String) extends Protocol
final case class Second(message : Double) extends Protocol
And you lose easy callback combination: no orElse method for you. Only hand-written
val receive : PartialFunction[Protocol, Unit] = {
case First(msg) => receiveOne(msg)
case Second(msg) => receiveTwo(msg)
}
And if you would like to add a bit of new functionality with trait Three then you would be busy with rewriting that boilerplate code.
Akka provides some useful predefined enhancements for actors. They add new functionality either by mixin (e.g. receive pipeline) or by delegating (e.g. reliable proxy). Proxy patterns are used pretty much in akka applications and they change protocol on the fly, adding control command to it. That could not be done that easily with typed actors. So instead of predefined utilities you would be forced to write you own implementations. And forsaken utilities would not be limited with FSM.
It is up to you decide whether typing improvement worth increased work. No one can give precise advise without deep understanding of your project.
Typed actors are very new; they're explicitly marked as experimental and not ready for production use.
Warning
This module is currently experimental in the sense of being the subject of active research. This means that API or semantics can change without warning or deprecation period and it is not recommended to use this module in production just yet—you have been warned.
(as of the time this is written)
I'd like to point out a confusion that seems to have surfaced here.
Casper, the "typed actors" you refer to are deprecated and will be even removed eventually, I have explained in much detail why that's the case here: Akka typed actors in Java. The link you found with Viktor Klang answering, is talking about Akka 1.2 which is "ancient" as of now (when 2.4 is the stable release).
Having that said, there is a new experimental module called "Akka Typed", to which Daenyth is referring to in his reply. That module may indeed become a new core abstraction, however it's not yet ready for prime time.
I recommend you give the typed modules: Akka Streams (the latest addition to Akka, which will become not experimental very soon) and
Akka Typed to see how Actors may become typed in the near future (perhaps). Then, actually look again at Actors and see which model best works for your use case. Untyped Actors have the advantage of being a true and tried mature module / model, so you can really trust them in that sense, if you want more types - Akka Streams has you covered in many cases, but not all, so then you may consider the experimental module (but be aware, we most likely will change the Typed API while maturing it).

How to use Reactive Streams for NIO binary processing?

Are there some code examples of using org.reactivestreams libraries to process large data streams using Java NIO (for high performance)? I'm aiming at distributed processing, so examples using Akka would be best, but I can figure that out.
It still seems to be the case that most (I hope not all) examples of reading files in scala resort to Source (non-binary) or direct Java NIO (and even things like Files.readAllBytes!)
Perhaps there is an activator template I've missed? (Akka Streams with Scala! is close addressing everything I need except the binary/NIO side)
Do not use scala.collection.immutable.Stream to consume files like this, the reason being that it performs memoization - that is, while yes it is lazy it will keep the entire stream buffered (memoized) in memory!
This is definitely not what you want when you think about "stream processing a file". The reason Scala's Stream works like this is because in a functional setting it makes complete sense - you can avoid calculating fibbonachi numbers again and again easily thanks to this for example, for more details see the ScalaDoc.
Akka Streams provides Reactive Streams implementations and provides a FileIO class that you could use here (it will properly back-pressure and pull the data out of the file only when needed and the rest of the stream is ready to consume it):
import java.io._
import akka.actor.ActorSystem
import akka.stream.scaladsl.{ Sink, Source }
object ExampleApp extends App {
implicit val sys = ActorSystem()
implicit val mat = FlowMaterializer()
FileIO.fromPath(Paths.get("/example/file.txt"))
.map(c ⇒ { print(c); c })
.runWith(Sink.onComplete(_ ⇒ { f.close(); sys.shutdown() } ))
}
Here are more docs about working with IO with Akka Streams
Note that this is for the current-as-of writing version of Akka, so the 2.5.x series.
Hope this helps!
We actually use akka streams to process binary files. It was a little tricky to get things going as there wasn't any documentation around this, but this is what we came up with:
val binFile = new File(filePath)
val inputStream = new BufferedInputStream(new FileInputStream(binFile))
val binStream = Stream.continually(inputStream.read).takeWhile(-1 != _).map(_.toByte)
val binSource = Source(binStream)
Once you have binSource, which is an akka Source[Byte] you can go ahead and start applying whatever stream transformations (map, flatMap, transform, etc...) you want to it. This functionality leverages the Source companion object's apply that takes an Iterable, passing in a scala Stream that should read in the data lazily and make it available to your transforms.
EDIT
As Konrad pointed out in the comments section, a Stream can be an issue with large files due to the fact that it performs memoization of the elements it encounters as it's lazily building out the stream. This can lead to out of memory situations if you are not careful. However, if you look at the docs for Stream there is a tip for avoiding memoization building up in memory:
One must be cautious of memoization; you can very quickly eat up large
amounts of memory if you're not careful. The reason for this is that
the memoization of the Stream creates a structure much like
scala.collection.immutable.List. So long as something is holding on to
the head, the head holds on to the tail, and so it continues
recursively. If, on the other hand, there is nothing holding on to the
head (e.g. we used def to define the Stream) then once it is no longer
being used directly, it disappears.
So taking that into account, you could modify my original example as follows:
val binFile = new File(filePath)
val inputStream = new BufferedInputStream(new FileInputStream(binFile))
val binSource = Source(() => binStream(inputStream).iterator)
def binStream(in:BufferedInputStream) = Stream.continually(in.read).takeWhile(-1 != _).map(_.toByte)
So the idea here is to build the Stream via a def and not assign to a valand then immediately get the iterator from it and use that to initialize the Akka Source. Setting things up this way should avoid the issues with momoization. I ran the old code against a big file and was able to produce an OutOfMemory situation by doing a foreach on the Source. When I switched it over to the new code I was able to avoid this issue.

How to get actor messages from stdin?

I would like to know if it's possible (and how) to get an akka actor to receive messages from stdin. Essentially, the idea would be for every line of input to be sent as a message to the actor, e.g.
> myprogram
DO X
DO Y
...
and then to have the actor receive messages "DO X", "DO Y", etc.
Is there a standard solution to do this?
I guess one way would be to do this:
spawn {
while(in.available) {
actor ! in.readLine
}
}
But then I'd have two actors (or one actor-based task and one actor) and I'd be using blocking IO (is that safe with actors, by the way?)... Also, it makes it harder to control the spawn block (e.g. to kill the task).
Added further follow ups from OP
I have a couple follow ups, if you will allow me...
Is there a performance hit using this solution (i.e. does CamelServiceManager start a lot of things? HTTP server, etc.)?
Got a good tutorial for beginners? I started reading Camel from the official Akka documentation, but it seems to assume more knowledge of Camel than I currently possess. For instance, I couldn't figure out how to use a custom java.io.InputStream as endpointUri.
You could use akka-camel together with the camel-stream component to let actors receive messages from stdin. Here's a working example:
import akka.actor.Actor
import akka.camel.{Message, CamelServiceManager, Consumer}
object Example extends App {
CamelServiceManager.startCamelService
Actor.actorOf[ExampleConsumer].start
}
class ExampleConsumer extends Actor with Consumer {
def endpointUri = "stream:in"
def receive = {
case msg: Message => println("received %s" format msg.bodyAs[String])
}
}
Update: Answers to the follow-up questions
The CamelServiceManager.startCamelService method starts a CamelContext and two Akka actors that register newly started Consumer actor endpoints at the CamelContext. No HTTP server is started.
Good introductions to Apache Camel are Apache Camel: Integration Nirvana article and chapter 1 of the Camel in Action book. The Appendix E of Camel in Action is an introduction to akka-camel.
Setting a custom InputStream at the endpoint URI is currently not possible with the camel-stream component.