@@ -48,30 +48,22 @@ func Ask(ctx context.Context, to *PID, message proto.Message, timeout time.Durat
48
48
return nil , ErrDead
49
49
}
50
50
51
- var messageContext * ReceiveContext
52
-
53
- switch msg := message .(type ) {
54
- case * internalpb.RemoteMessage :
55
- var actual proto.Message
56
- if actual , err = msg .GetMessage ().UnmarshalNew (); err != nil {
57
- return nil , ErrInvalidRemoteMessage (err )
58
- }
59
- messageContext = newReceiveContext (ctx , NoSender , to , actual ).WithRemoteSender (msg .GetSender ())
60
- default :
61
- messageContext = newReceiveContext (ctx , NoSender , to , message ).WithRemoteSender (RemoteNoSender )
51
+ receiveContext , err := toReceiveContext (ctx , to , message )
52
+ if err != nil {
53
+ return nil , err
62
54
}
63
55
64
- to .doReceive (messageContext )
56
+ to .doReceive (receiveContext )
65
57
66
58
// await patiently to receive the response from the actor
67
59
select {
68
- case response = <- messageContext .response :
69
- to .setLastProcessingDuration ( time . Since ( to . getLastProcessingTime ()) )
60
+ case response = <- receiveContext .response :
61
+ to .recordLatestReceiveDurationMetric ( ctx )
70
62
return
71
63
case <- time .After (timeout ):
72
- to .setLastProcessingDuration ( time . Since ( to . getLastProcessingTime ()) )
64
+ to .recordLatestReceiveDurationMetric ( ctx )
73
65
err = ErrRequestTimeout
74
- to .toDeadletterQueue (messageContext , err )
66
+ to .toDeadletterQueue (receiveContext , err )
75
67
return
76
68
}
77
69
}
@@ -82,66 +74,41 @@ func Tell(ctx context.Context, to *PID, message proto.Message) error {
82
74
return ErrDead
83
75
}
84
76
85
- var messageContext * ReceiveContext
86
-
87
- switch msg := message .(type ) {
88
- case * internalpb.RemoteMessage :
89
- var (
90
- actual proto.Message
91
- err error
92
- )
93
-
94
- if actual , err = msg .GetMessage ().UnmarshalNew (); err != nil {
95
- return ErrInvalidRemoteMessage (err )
96
- }
97
- messageContext = newReceiveContext (ctx , NoSender , to , actual ).WithRemoteSender (msg .GetSender ())
98
- default :
99
- messageContext = newReceiveContext (ctx , NoSender , to , message ).WithRemoteSender (RemoteNoSender )
77
+ receiveContext , err := toReceiveContext (ctx , to , message )
78
+ if err != nil {
79
+ return err
100
80
}
101
81
102
- to .doReceive (messageContext )
103
- to .setLastProcessingDuration ( time . Since ( to . getLastProcessingTime ()) )
82
+ to .doReceive (receiveContext )
83
+ to .recordLatestReceiveDurationMetric ( ctx )
104
84
return nil
105
85
}
106
86
107
87
// BatchTell sends bulk asynchronous messages to an actor
88
+ // The messages will be processed one after the other in the order they are sent
89
+ // This is a design choice to follow the simple principle of one message at a time processing by actors.
108
90
func BatchTell (ctx context.Context , to * PID , messages ... proto.Message ) error {
109
- if ! to .IsRunning () {
110
- return ErrDead
111
- }
112
-
113
- for i := 0 ; i < len (messages ); i ++ {
114
- message := messages [i ]
115
- messageContext := newReceiveContext (ctx , NoSender , to , message ).WithRemoteSender (RemoteNoSender )
116
- to .doReceive (messageContext )
91
+ // messages are processed one after the other
92
+ for _ , mesage := range messages {
93
+ if err := Tell (ctx , to , mesage ); err != nil {
94
+ return err
95
+ }
117
96
}
118
- to .setLastProcessingDuration (time .Since (to .getLastProcessingTime ()))
119
97
return nil
120
98
}
121
99
122
100
// BatchAsk sends a synchronous bunch of messages to the given PID and expect responses in the same order as the messages.
123
101
// The messages will be processed one after the other in the order they are sent
124
102
// This is a design choice to follow the simple principle of one message at a time processing by actors.
125
103
func BatchAsk (ctx context.Context , to * PID , timeout time.Duration , messages ... proto.Message ) (responses chan proto.Message , err error ) {
126
- if ! to .IsRunning () {
127
- return nil , ErrDead
128
- }
129
-
130
104
responses = make (chan proto.Message , len (messages ))
131
105
defer close (responses )
132
-
133
- for i := 0 ; i < len (messages ); i ++ {
134
- receiveContext := newReceiveContext (ctx , NoSender , to , messages [i ])
135
- to .doReceive (receiveContext )
136
- select {
137
- case result := <- receiveContext .response :
138
- responses <- result
139
- to .setLastProcessingDuration (time .Since (to .getLastProcessingTime ()))
140
- case <- time .After (timeout ):
141
- to .setLastProcessingDuration (time .Since (to .getLastProcessingTime ()))
142
- to .toDeadletterQueue (receiveContext , ErrRequestTimeout )
143
- return nil , ErrRequestTimeout
106
+ for _ , mesage := range messages {
107
+ response , err := Ask (ctx , to , mesage , timeout )
108
+ if err != nil {
109
+ return nil , err
144
110
}
111
+ responses <- response
145
112
}
146
113
return
147
114
}
@@ -499,3 +466,17 @@ func RemoteSpawn(ctx context.Context, host string, port int, name, actorType str
499
466
}
500
467
return nil
501
468
}
469
+
470
+ // toReceiveContext creates a ReceiveContext provided a message and a receiver
471
+ func toReceiveContext (ctx context.Context , to * PID , message proto.Message ) (* ReceiveContext , error ) {
472
+ switch msg := message .(type ) {
473
+ case * internalpb.RemoteMessage :
474
+ actual , err := msg .GetMessage ().UnmarshalNew ()
475
+ if err != nil {
476
+ return nil , ErrInvalidRemoteMessage (err )
477
+ }
478
+ return newReceiveContext (ctx , NoSender , to , actual ).WithRemoteSender (msg .GetSender ()), nil
479
+ default :
480
+ return newReceiveContext (ctx , NoSender , to , message ).WithRemoteSender (RemoteNoSender ), nil
481
+ }
482
+ }
0 commit comments