DEV Community

SameX
SameX

Posted on

HarmonyOS Actor model practical: from concurrent security to distributed scaling

As a development veteran who struggled in the Hongmeng distributed system, the Actor model once confused me - until it was used to solve the distributed lock problem in the order system.This article combines practical experience and shares the core principles and implementation skills of the Actor model to help you avoid the pitfalls of concurrent programming.

1. Actor model core: message-driven concurrency philosophy

1.1 Shared memory vs Message driver (compare the essence)

Dimensions Shared Memory Model Actor Model (Message Driven)
Data security Need to manually add locks, which is prone to competition Status isolation, naturally avoiding data competition
Programming complexity Lock mechanism increases mental burden Focus on messaging, clearer logic
Distributed Scaling High cost of sharing memory across nodes Message Queues naturally support distributed

Practical case: Bank transfer scenario

  • Shared memory: Need to lock the account balance, it may be deadlocked
  • Actor model: Each account is an independent actor, and the transfer is passed through message and is lock-free.

2. Cangjie Actor Programming: Implementation of State Isolation

2.1 The core role of receiver func

actor Account {
private var balance: Int64 // Complete status isolation

    init(initial: Int64) {
        balance = initial
    }

// The core function for receiving messages
    receiver func transfer(amount: Int64, to: ActorRef<Account>) {
        if balance >= amount {
            balance -= amount
to.send(message: Deposit(amount: amount)) // Send a message to the target account
        }
    }

    receiver func deposit(amount: Int64) {
        balance += amount
    }
}

// Call method
let from = spawn(Account(initial: 1000))
let to = spawn(Account(initial: 500))
from.send(message: Transfer(amount: 200, to: to))
Enter fullscreen mode Exit fullscreen mode

Key Features:

  • The status is managed by the actor itself, and external operations can only be operated through messages.
  • receiver func ensures sequential processing of messages without the need for additional synchronization mechanisms

3. Distributed expansion: Smooth migration from stand-alone to cluster

3.1 Three core components of distributed actors

  1. Actor Registration Center
  2. Maintain global Actor address mapping table
  3. Support cross-node Actor reference parsing

  4. Distributed Message Queue

  5. Cross-node message delivery based on DDS

  6. Ensure order and reliability of messages

  7. Actor migration mechanism

// Migrate the Actor on Node A to Node B
   actorMigrator.migrate(
       actorId: "orderActor",
       targetNode: "nodeB",
       state: actorStateSnapshot
   )
Enter fullscreen mode Exit fullscreen mode

3.2 Practical architecture: e-commerce order system

┌─────────────┐    ┌─────────────┐    ┌─────────────┐  
│ Order Actor │────→│ Payment Actor │───→│ Inventory Actor │
│ (Node A) │ │ (Node B) │ │ (Node C) │
└─────────────┘    └─────────────┘    └─────────────┘  
        ↑                ↑                ↑  
        └────────────────┼────────────────┘  
                 ┌──────────────────────┐  
│ Distributed Message Queue (based on DDS) │
                 └──────────────────────┘  
Enter fullscreen mode Exit fullscreen mode

** Advantages**:

  • When the order volume increases suddenly, the Actor node can be expanded dynamically
  • Single Actor failure does not affect overall system operation

4. Guide to performance optimization and pit avoidance

4.1 Message processing optimization

  • Batch processing: Merge small messages to reduce communication overhead
  • Async reply: Avoid synchronous waiting blocking Actor

4.2 Common Traps

  1. Newstorm:
  2. Control the frequency of message between actors to avoid flooding
  3. Status expansion:
  4. Regularly clean the useless state of the Actor to prevent memory leaks
  5. Network Partition:
    • 实现Actor断线重连机制,保证最终一致性

Top comments (0)