Handlers

Define how actors process messages.

The Handler Trait

For each message type an actor can receive, you implement the Handler trait:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

The handler receives:

  • &mut self — Mutable access to actor state
  • msg — The message being handled
  • ctx — The actor's context for spawning, timers, etc.

Async Handlers

For handlers that need to perform async operations (I/O, network calls), use AsyncHandler:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Important: While an async handler is running, the actor is blocked and cannot process other messages. For true concurrent processing, spawn separate actors.

Sending to Async Handlers

Use the async-specific send methods:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

Multiple Handlers

An actor can handle multiple message types:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

Using Context in Handlers

The context provides powerful capabilities within handlers:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

Stream Handlers

Handle items from async streams with StreamHandler:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

Best Practices

Keep handlers fast

Sync handlers should complete quickly. Use AsyncHandler for I/O operations.

Return meaningful results

Use Result<T, E> types to communicate success/failure to callers.

Use the right handler type

Handler for CPU-bound work, AsyncHandler for I/O, StreamHandler for continuous data.

Don't block in sync handlers

Avoid std::thread::sleep or blocking I/O. It blocks all message processing.

Avoid panicking in handlers

Return errors instead. Panics trigger supervision but lose the response.

Handler Types Comparison

TypeUse CaseSend Method
HandlerSync operations, state updatessend()
AsyncHandlerNetwork, file I/O, databasesend_async()
StreamHandlerContinuous data (TCP, events)ctx.add_stream()

Next Steps