[컴] 정리 - akka in action 2014

 

 

 

akka 의 문법이 많이 바뀌었다. 이 글은 그저 원리를 이해하는 데 초점을 두자.


책-akka in action, 2014


Akka also provides a runtime. The core of the runtime is the basic actor services and a flexible means of configuring the other modules that you would like to use.

There is a microkernel called Play-mini available which you can use to deploy your applications


Akka application made up of? Well, the answer is, Actors. Akka is based on the Actor programming model


Option1 : Share State Approach three threading pitfalls

  1. thread starvation
  2. race conditions
  3. deadlock

Everything you directly still eventually runs on threads and low level concurrency primitives.

Akka uses the java.util.concurrent library to coordinate message processing and takes great care to minimize the number of locks used to an absolute bare minimum. 10 August 2020


p.26

When you look at the topic of concurrency in the general sense, there really are only two types:

shared-state concurrency and message passing for concurrency.


Applications tend to favor the use of shared-state concurrency with threads and locks,

whereas larger systems favor message passing at the macro level (unless, of course, a database is being used as a rendezvous).


p. 29

Scala has always had actors and futures, as has Akka. However, Akka’s design and implementation of actors and futures has evolved far past that of Scala’s implementation.


Akka brings together a solid set of tools

  • Actors
  • Futures
  • Timers
  • Callbacks/Closures

Error handling (a.k.a. Resiliency) Non-blocking by default


P. 30

One of Akka’s core philosophies is that errors and failures are part of the design of any good application, not things to be avoided. Your application will be affected by real life at some point.


P. 40

If you don’t want to be spinning up threads manually, then what’s the better option? Well, it’s thread pools.

Thread pools are important in concurrent programming, and are equally important when programming with Akka, although we don’t often use them directly.


P. 50

Immutable data structures

  • linked list

If you give the value list to someone, then you don’t need to protect it

For instance, prepending to a list is a fast operation. We can grow this list from any point we choose by simply prepending elements to various places.

What about appending? Appending to a List creates an entirely new list


p. 51

Immutable data structures

  • Immutable maps

Many map implementations use trees (e.g. scala.collection.immutable.TreeMap , and slightly less obviously, any linked-bucket map)

If we want to remove E , then we need to have something that looks like Figure 2.10. Anyone who has a reference to D won’t notice a thing.

D —> C
     +
     +--> E --> F
             /
D' -->C'    /
    +      /
    +---> F'

You send an actor a message that tells it to do something, which it does presumably quickly and well, and then it tells you what it did


Actors only do one thing at a time; that’s the model of concurrency.

If you want to have more than one thing happen simultaneously, then you need to create more than one actor to do that work.


P. 67


p.70

In order for Akka to be able to do the cool things that it does, and to work quickly and deterministically,

it needs you to make sure that your messages are immutable.


  • An actor is behaviour
  • Add behaviour by adding actors

p, 75

Actor programming is reactive programming. Another way to say this is that it’s event-driven programming. 17:29 책-akka in action

P. 77

The future

P. 81

But one of the things that actors don’t do well is compose.

The futures implementation in Akka allows us to set up sequential pipelines of code that run asynchronously to other pipelines 11 August 2020


P.82

The actor itself had three methods

The different methods signified that the call could be

  • non-blocking,(!)
  • blocking,(!!)
  • or Future-based(!!!)

, respectively


A future can be used to coordinate responses, and then pipe that response message to another actor instance.


For example, one thing we might do in our day-to-day work may be to create a couple of queues for different threads to use for communication.

One side may pull work out from their queue while the other side polls, or otherwise waits, on their own queue for results.

With futures, we don’t need to think in that manner anymore. We would create a future to do the work, and then compose another future on top of it to process the results.


P. 83

The rest

  • The EventBus
  • The scheduler
  • Dataflow concurrency
  • Message routing
  • Agents
  • and others

  • The EventBus
  • want to broadcast events, cerntain messages
  • The scheduler
  • that executes functions at timed intervals or single operations at some point in the future. It even provides a special construct for sending messages to specific actors in the future

Dataflow concurrency

Well, it’s not actually mutable in the traditional sense, so the sharing isn’t quite the same as we’re used to in shared-state concurrency.

These aren’t variables but are values and are thus immutable.


Agents are effectively actors and thus provide the same single-threaded guarantees that actors provide,

but without the need to send messages to them in order to obtain their values.


P. 87

When it comes to building highly concurrent and fault-tolerant applicationson the JVM, Akka is a solid choice.



p.91

메시지가 가면, ActorRef 가 받는다. 그리고 Dispatcher 를 이용해서 message 를 actor의 mailbox (queue) 에 넣는다.

dispatcher 가 mailbox 를 thread 에 놓고, mailbox 가 실행되면, mailbox 는 message 들을 dequeue 한다. mailbox 가 messages 를 actor 의 receive method 로 보내서 처리한다.


Actors do one thing at a time, they do it very well, and then they quickly move on.

  1. It’s up to you to do things quickly. If you’re going to calculate π to 8 bazillion decimal places without ever leaving the receive method, then don’t expect your actor to be all that responsive.

  2. You can always create weird ways of breaking out of this model (e.g., start modifying some global variables, sharing your state with the world, and so on...). Don’t.


P. 95

Akka’s got you covered here. when you create an actor it has a globally unique identity and you can locate it.


p. 101

the ActorSystem it as the root of a collection of actors


p. 106

Don’t subvert the actor programming paradigm.

Any mutable actor data must only be accessed (that means reading too) in the actor’s receive method.

me: actor 는 한번에 하나의 일만 하니, receive method 에서만 접근한다면, race condition 이 발생하지 않을 것이다.


P. 108

akka 가 Actor 를 new 로 생성할 수 없다. factory method 로만 생성이 가능하다. 그래서 parameter 로도 전달을 할 수 없다. 무조건 ActorRef 를 전달해야 한다.

  • context.actorOf : 이것은 ActorRef 를 만들어서 현재 actor 의 child 로 묶어준다.
  • system.actorOf

로 생성하는데, actorOf 는 ActorRef 를 return 한다. 12 August 2020


// ! 의 declaration
def ! (message: Any)(implicit sender: ActorRef = null): Unit

// tell is defined as
def tell(msg: Any, sender: ActorRef): Unit

! 를 이용하면, 기본적으로 message sender 의 ActorRef 를 보내게 된다.

So, if you’re inside an actor and want to null out the sender, then you can easily specify the sender explicitly:

someActorSomewhere.!("This is a message")(Actor.noSender)

// so we can do this
someActorSomewhere.tell("This is a message", Actor.noSender)

Inside the receiving actor, we can get the reference to the sender using an aptly named method:

def sender: ActorRef

def receive = {
  case GiveMeControl =>
    log info ("Plane giving control.")
    sender ! controls

  case AltitudeUpdate(altitude) =>
    log info (s"Altitude is now: $altitude")
}

sender 는 함수여서, 부르는 시점에 어떤 값이 올지 정해진다. 그래서 closure 등을 사용할 때는 미리 val 에 할당을 한 이후에 사용하는 것이 안전하다.


p. 120

Null sender

when the sender is null

When this situation occurs, Akka attaches a default sender called the dead letter office, which is a single actor instance per ActorSystem

and can be accessed directly from the ActorSystem via the deadLetters method.


p. 121

Forwarding

def forward (message: Any)(implicit context: ActorContext): Unit


The ActorSystem is special because it is always the root of its own hierarchy and it can never appear anywhere else in the tree but the root.

p. 123

it’s not an actor; it’s a house for actors

Can Access

  • System configuration
  • default scheduler
  • have access to a generally accessible event stream
  • you can hook things up to it directly, if you’d like.
  • we can obtain references to currently running actors in its hierarchy
  • shut the system down, as well as stop individual actors.

P. 124

ActorSystem s must have a globally unique name in your appli- cation

the actors that live within it must also have a unique name


p. 152





 


User Guardian Actor

We know that no actor we create can exist without a parent - something has to own it.

The user guardian actor is the parent of all actors we create from the ActorSystem


System Guardian Actor

For internal actors that Akka creates in order to assist you, there is the system guardian actor, which serves the same purpose as the user guardian actor, but for “system” actors.


Scheduler

We’ve met the scheduler before and, while you could always instantiate one for yourself,

the default one lives as an ActorSystem child.


Event Stream


Settings

Akka uses a new configuration system that is useful for configuring Akka and your application.

You can access it from the ActorSystem


p.153

Actor paths

val system = ActorSystem("PlaneSimulation")
val plane = system.actorOf(Props[Plane], "Plane")

akka://PlaneSimulation@{host}:{port}/user/Plane


p. 160

Akka team have opted to use a HashedWheelTimer in their scheduler implementation

It trades off timer resolution and microsecond accuracy for low overhead.

the scheduler has a default resolution of only 100 milliseconds.


actorRef = actorFor("/user/actor/path")
actorRef = actorFor(List("user/action/path", "user2/action/path")

actorFor 로 actor 를 찾을 수 있다.


p. 188

Any actor can watch any other actor for death using the ActorContext ’s watch and unwatch methods.

댓글 없음:

댓글 쓰기