تصميم أنظمة Actor
تعلّم تصميم التسلسلات الهرمية لـ actors وتنفيذها، وتعريف سلوكيات actors، وإرسال الرسائل واستقبالها
تصميم أنظمة Actor درس مجاني في Scala for Backend Engineering & Functional Programming على CoddyKit. هذا هو الدرس 2 من أصل 3. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Scala for Backend Engineering & Functional Programming، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Scala for Backend Engineering & Functional Programming 3 دروس في المجموع.
بعض أجزاء هذا الدرس لم تُترجم بعد وتظهر باللغة الإنجليزية.
Design Actor Systems: Intro
Welcome to Lesson 2! In the previous lesson, we learned the basics of the Akka Actor Model. Now, let's dive into designing Akka Actor Systems.
A well-designed actor system is robust, scalable, and easy to maintain. We'll explore how to structure your actors, define their behaviors, and enable them to communicate effectively.
Understanding Actor Hierarchies
Akka actors are organized in a tree-like hierarchy, much like a file system. Every actor, except the 'root' actor, has a parent.
- Parent-Child Relationship: An actor that creates another actor becomes its parent.
- Supervision: This hierarchy is crucial for Akka's fault tolerance. Parents are responsible for supervising their children (more on this in the next lesson!).
- Path-based Addressing: Each actor has a unique path, reflecting its position in the hierarchy, like
/user/parentActor/childActor.
Setting Up Your ActorSystem
The ActorSystem is the entry point for all Akka applications. It manages the resources needed for actors, including thread pools and schedulers.
You create it once per application and then use it to create your top-level actors. It's like the container for your entire actor application.
Try running this simple code to create an 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()
}
}Defining Actor Behavior
An actor's behavior determines how it reacts to different messages. In Scala, you define this by extending the Actor trait and implementing the receive method.
- The
receivemethod is a partial function that matches incoming messages to specific actions. - Each actor processes messages one by one, sequentially, ensuring thread safety for its internal state.
ActorRef: The Actor's Address
You don't directly interact with actor instances. Instead, you send messages to an ActorRef. Think of ActorRef as a postal address for an actor.
- It's a handle that represents a specific actor within the system.
- Messages sent to an
ActorRefare placed in the actor's mailbox. - You obtain an
ActorRefwhen you create an actor usingactorOf.
Sending Messages to Actors
The primary way actors communicate is by sending messages. The most common way to send a message is using the ! (pronounced 'tell') method.
receiverActorRef ! "Your message here"
The tell method is asynchronous and fire-and-forget. It sends the message and doesn't wait for a reply.
Let's combine creating an actor and sending it messages:
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()
}
}Creating Child Actors
Actors can create other actors, forming the hierarchy we discussed. A parent actor creates its child actors using context.actorOf.
context.actorOf: Used by an actor to create its children.system.actorOf: Used by the application to create top-level (guardian) actors.
Creating child actors helps in organizing your system, delegating tasks, and isolating failures.
Parent-Child Communication
Actors communicate by sending messages to each other's ActorRef. A child actor can get its parent's ActorRef via context.parent. To reply to the sender of a message, an actor can use sender().
Let's see an example where a parent creates a child, tells it to do work, and the child reports back when done:
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."))
}
}Stopping Actors Gracefully
Actors should be stopped gracefully when they are no longer needed to release resources. You can stop an actor in a few ways:
context.stop(self): An actor stops itself.context.stop(childRef): A parent stops one of its children.system.stop(actorRef): For top-level actors, though usually, you stop the entire system.
When an actor stops, it processes all messages in its mailbox before terminating. Its children are also stopped recursively.
Quick Check: Actor Design
Consider the following Akka actor code snippet. What is the correct way for MyChildActor to send a message back to its creating parent, MyParentActor, if MyParentActor was the sender of the initial 'request' message?
Recap: Designing Actor Systems
Great job! In this lesson, we've covered key aspects of designing Akka Actor Systems:
- Actors are organized in hierarchies, which are vital for supervision and structure.
- The
ActorSystemis your application's entry point for Akka. - You define actor behavior using the
receivemethod. ActorRefis the address for sending messages.- Actors communicate asynchronously using the
!(tell) method. - Parents create children with
context.actorOf, and children can reply usingsender(). - Actors can be stopped gracefully using
context.stop().
Next, we'll delve deeper into Akka's powerful supervision strategies and how to handle failures gracefully!
الأسئلة الشائعة
هل درس «تصميم أنظمة Actor» مجاني؟
نعم — نص درس «تصميم أنظمة Actor» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Scala for Backend Engineering & Functional Programming، انتقل إلى CoddyKit PRO. تتضمن دورة Scala for Backend Engineering & Functional Programming 3 دروس في المجموع.
ماذا ستتعلم في «تصميم أنظمة Actor»؟
تعلّم تصميم التسلسلات الهرمية لـ actors وتنفيذها، وتعريف سلوكيات actors، وإرسال الرسائل واستقبالها تتمرن على Scala for Backend Engineering & Functional Programming مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Scala for Backend Engineering & Functional Programming؟
لا تُشترط خبرة سابقة. Scala for Backend Engineering & Functional Programming على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 3.
كم من الوقت يستغرق درس «تصميم أنظمة Actor»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Scala for Backend Engineering & Functional Programming هذا؟
نعم. كل درس في Scala for Backend Engineering & Functional Programming يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- أساسيات نموذج Akka Actor
- تصميم أنظمة Actor
- الإشراف وتحمل الأعطال