0Pricing
Scala for Backend Engineering & Functional Programming · レッスン

アクターシステムの設計

アクター階層の設計・実装、アクターの振る舞いの定義、メッセージの送受信方法を学びます。

「アクターシステムの設計」はCoddyKit上の無料Scala for Backend Engineering & Functional Programmingレッスンです。 これはレッスン2/3です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはScala for Backend Engineering & Functional Programming学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Scala for Backend Engineering & Functional Programmingコースには全3レッスンが含まれています。

アクターシステムの設計:概要

レッスン2へようこそ。前のレッスンでは、Akka Actor Modelの基本を学びました。ここからはAkkaアクターシステムの設計について詳しく見ていきます。

適切に設計されたアクターシステムは、堅牢で、拡張性があり、保守しやすいものです。アクターの構成、振る舞いの定義、効果的な通信方法について学びます。

アクター階層を理解する

Akkaのアクターは、ファイルシステムのようなツリー状の階層で構成されます。'root'アクターを除くすべてのアクターには、親が存在します。

  • 親子関係:別のアクターを生成したアクターが、そのアクターの親になります。
  • スーパービジョン:この階層は、Akkaのフォールトトレランスにとって重要です。親は子を監督する責任を負います(詳しくは次のレッスンで説明します)。
  • パスによるアドレス指定:各アクターには、/user/parentActor/childActorのように階層内での位置を表す一意のパスがあります。

ActorSystemをセットアップする

ActorSystemは、すべてのAkkaアプリケーションのエントリーポイントです。スレッドプールやスケジューラーなど、アクターに必要なリソースを管理します。

アプリケーションごとに一度だけ作成し、その後、最上位のアクターを作成するために使用します。アクターアプリケーション全体を収めるコンテナのようなものです。

次の簡単なコードを実行して、ActorSystemを作成してみましょう。

import akka.actor.ActorSystem

object AkkaSystemApp {
  def main(args: Array[String]): Unit = {
    // Create an ActorSystem with a unique name
    val system = ActorSystem("MyFirstActorSystem")
    println("ActorSystem created: " + system.name)

    // Remember to terminate the system when done!
    system.terminate()
  }
}

アクターの振る舞いを定義する

アクターの振る舞いによって、さまざまなメッセージに対する反応が決まります。Scalaでは、Actorトレイトを拡張し、receiveメソッドを実装して定義します。

  • receiveメソッドは部分関数であり、受信したメッセージを特定の処理に対応付けます。
  • 各アクターはメッセージを1件ずつ順番に処理するため、内部状態のスレッドセーフ性が保たれます。

ActorRef:アクターのアドレス

アクターのインスタンスを直接操作することはありません。代わりに、ActorRefへメッセージを送信します。ActorRefは、アクターの宛先となる郵便アドレスのようなものだと考えてください。

  • システム内の特定のアクターを表すハンドルです。
  • ActorRefに送信されたメッセージは、アクターのメールボックスに入れられます。
  • actorOfを使ってアクターを作成すると、ActorRefを取得できます。

アクターにメッセージを送信する

アクターが通信する主な方法は、メッセージを送信することです。最も一般的な送信方法は、!(「tell」と読みます)メソッドを使うことです。

receiverActorRef ! "Your message here"

tellメソッドは非同期で、ファイア・アンド・フォーゲット方式です。メッセージを送信しますが、返信を待ちません。

アクターの作成とメッセージの送信を組み合わせてみましょう。

import akka.actor.{Actor, ActorRef, Props, ActorSystem}

// 1. Define the actor's behavior
class GreeterActor extends Actor {
  def receive = {
    case "hello" => println(s"Greeter: Hello from ${self.path.name}!")
    case msg: String => println(s"Greeter: Received message: '$msg'")
    case _ => println("Greeter: Received something unexpected!")
  }
}

object SimpleActorApp {
  def main(args: Array[String]): Unit = {
    // 2. Create the ActorSystem
    val system = ActorSystem("GreeterSystem")

    // 3. Create a top-level actor and get its ActorRef
    val greeter: ActorRef = system.actorOf(Props[GreeterActor], "myGreeter")
    
    // 4. Send messages to the actor using '!'
    greeter ! "hello"
    greeter ! "How are you doing today?"
    greeter ! 123 // This will match the _ case

    // Give actors time to process messages, then terminate
    Thread.sleep(1000)
    system.terminate()
  }
}

子アクターを作成する

アクターは別のアクターを作成でき、先ほど説明した階層を形成します。親アクターはcontext.actorOfを使って子アクターを作成します。

  • context.actorOf:アクターが子アクターを作成するために使用します。
  • system.actorOf:アプリケーションが最上位(guardian)アクターを作成するために使用します。

子アクターを作成すると、システムの整理、タスクの委譲、障害の分離に役立ちます。

親子間で通信する

アクターは、互いのActorRefにメッセージを送信して通信します。子アクターはcontext.parentを使って親のActorRefを取得できます。メッセージの送信元に返信するには、sender()を使用します。

親が子を作成し、作業を指示して、完了時に子が報告する例を見てみましょう。

import akka.actor.{Actor, ActorRef, Props, ActorSystem}
import scala.concurrent.ExecutionContext.Implicits.global

// Child Actor Definition: Does work and replies to sender
class ChildActor extends Actor {
  def receive = {
    case "work" =>
      println(s"ChildActor (${self.path.name}): Doing work from ${sender().path.name}")
      sender() ! "done" // Reply 'done' to the sender (parent)
  }
}

// Parent Actor Definition: Creates child, sends work, receives reply
class ParentActor extends Actor {
  // Create a child actor when the parent starts
  val child: ActorRef = context.actorOf(Props[ChildActor], "myChild")

  def receive = {
    case "start" =>
      println("ParentActor: Kicking off child's work.")
      child ! "work" // Tell the child to do 'work'
    case "done" =>
      println(s"ParentActor: Child ${sender().path.name} reported 'done'.")
      context.stop(child) // Stop the child actor
      context.stop(self)   // Stop the parent actor
  }
}

object HierarchyApp {
  def main(args: Array[String]): Unit = {
    val system = ActorSystem("HierarchySystem")
    val parent: ActorRef = system.actorOf(Props[ParentActor], "parentActor")
    parent ! "start" // Start the interaction

    // Wait for the system to terminate (actors will stop themselves)
    system.whenTerminated.onComplete(_ => println("ActorSystem terminated."))
  }
}

アクターを適切に停止する

不要になったアクターは、リソースを解放するために適切に停止する必要があります。アクターを停止する方法はいくつかあります。

  • context.stop(self):アクター自身を停止します。
  • context.stop(childRef):親が子の1つを停止します。
  • system.stop(actorRef):最上位アクターに使用します。ただし通常は、システム全体を停止します。

アクターが停止すると、終了する前にメールボックス内のすべてのメッセージを処理します。子アクターも再帰的に停止されます。

クイック確認:アクター設計

次のAkkaアクターコードを考えてみましょう。MyParentActorが最初の「request」メッセージの送信元だった場合、MyChildActorが作成元の親であるMyParentActorにメッセージを送り返す正しい方法はどれでしょうか。

振り返り:アクターシステムの設計

よくできました。このレッスンでは、Akkaアクターシステムの設計に関する重要な点を学びました。

  • アクターは階層で構成され、スーパービジョンと構造化において重要な役割を果たします。
  • ActorSystemは、アプリケーションにおけるAkkaのエントリーポイントです。
  • receiveメソッドを使ってアクターの振る舞いを定義します。
  • ActorRefは、メッセージ送信用のアドレスです。
  • アクターは!(tell)メソッドを使って非同期に通信します。
  • 親はcontext.actorOfで子を作成し、子はsender()を使って返信できます。
  • アクターはcontext.stop()を使って適切に停止できます。

次は、Akkaの強力なスーパービジョン戦略と、障害を適切に処理する方法についてさらに詳しく学びます。

よくある質問

「アクターシステムの設計」レッスンは無料ですか?

はい。「アクターシステムの設計」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Scala for Backend Engineering & Functional Programmingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Scala for Backend Engineering & Functional Programmingコースには全3レッスンが含まれています。

「アクターシステムの設計」で何を学びますか?

アクター階層の設計・実装、アクターの振る舞いの定義、メッセージの送受信方法を学びます。 ブラウザで直接実行するハンズオンコードでScala for Backend Engineering & Functional Programmingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Scala for Backend Engineering & Functional Programmingを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのScala for Backend Engineering & Functional Programmingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/3です。

「アクターシステムの設計」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このScala for Backend Engineering & Functional Programmingレッスンでコードを書いて実行できますか?

はい。すべてのScala for Backend Engineering & Functional Programmingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Akkaアクターモデルの基礎
  2. アクターシステムの設計
  3. スーパービジョンと耐障害性
← Scala for Backend Engineering & Functional Programmingに戻る