@@ -3,64 +3,71 @@ use tokio::sync::broadcast;
3
3
use tracing:: { info} ;
4
4
use crate :: connection:: Connection ;
5
5
use std:: process:: { Command , Stdio } ;
6
+ use std:: sync:: Arc ;
6
7
use crate :: message:: { RequestMessage , ResponseMessage } ;
7
8
8
9
9
10
type Receiver = broadcast:: Receiver < ( String , RequestMessage ) > ;
10
11
pub struct Handler {
11
12
cmd_rx : Receiver ,
12
- connection : Connection ,
13
- publish_topic : String ,
13
+ connection : Arc < Connection > ,
14
+ publish_topic : Arc < String > ,
14
15
}
15
16
16
17
17
18
18
19
impl Handler {
19
20
pub fn new ( cmd_rx : Receiver , connection : Connection , publish_topic : String ) -> Self {
20
- Self { cmd_rx, connection, publish_topic}
21
+ Self { cmd_rx, connection : Arc :: new ( connection ) , publish_topic : Arc :: new ( publish_topic ) }
21
22
}
22
23
23
- pub async fn run ( & mut self , _shutdown_rx : broadcast:: Receiver < bool > ) {
24
-
25
- while let Ok ( ( _, cmd) ) = self . cmd_rx . recv ( ) . await {
26
- info ! ( "begin to handle cmd: {:?}" , & cmd) ;
27
- match cmd {
28
- RequestMessage :: Cmd { command, request_id } => {
29
- let command_parsed = shellish_parse:: parse ( & command, false ) ;
30
- let command_parsed = match command_parsed {
31
- Ok ( result) => result,
32
- Err ( e) => {
33
- let _ = self . connection . publish_response ( & self . publish_topic , ResponseMessage :: Err { request_id : request_id. clone ( ) , message : format ! ( "{}" , e) } ) . await ;
34
- continue ;
35
- }
36
- } ;
37
-
38
- let mut seq: u32 = 1 ;
39
- let mut command = Command :: new ( & command_parsed[ 0 ] ) ;
40
- command. args ( & command_parsed[ 1 ..] ) ;
41
-
42
- command. stdout ( Stdio :: piped ( ) ) . stderr ( Stdio :: piped ( ) ) ;
43
- match command. spawn ( ) {
44
- Ok ( mut child) => {
45
- let pid = child. id ( ) ;
46
- if let Some ( stdout) = child. stdout . take ( ) {
47
- let reader = BufReader :: new ( stdout) ;
48
- for line in reader. lines ( ) . filter_map ( |line| line. ok ( ) ) {
49
- //TODO: handle publish error
50
- let _ = self . connection . publish_response (
51
- & self . publish_topic , ResponseMessage :: Ok { request_id : request_id. clone ( ) , data : line, seq : seq, pid : pid} ) . await ;
52
- seq +=1 ;
53
- }
24
+ async fn run_command ( connection : Arc < Connection > , cmd : RequestMessage , publish_topic : Arc < String > ) {
25
+ match cmd {
26
+ RequestMessage :: Cmd { command, request_id } => {
27
+ let command_parsed = shellish_parse:: parse ( & command, false ) ;
28
+ let command_parsed = match command_parsed {
29
+ Ok ( result) => result,
30
+ Err ( e) => {
31
+ let _ = connection. publish_response ( & publish_topic, ResponseMessage :: Err { request_id : request_id. clone ( ) , message : format ! ( "{}" , e) } ) . await ;
32
+ return ;
33
+ }
34
+ } ;
35
+
36
+ let mut seq: u32 = 1 ;
37
+ let mut command = Command :: new ( & command_parsed[ 0 ] ) ;
38
+ command. args ( & command_parsed[ 1 ..] ) ;
39
+
40
+ command. stdout ( Stdio :: piped ( ) ) . stderr ( Stdio :: piped ( ) ) ;
41
+ match command. spawn ( ) {
42
+ Ok ( mut child) => {
43
+ let pid = child. id ( ) ;
44
+ if let Some ( stdout) = child. stdout . take ( ) {
45
+ let reader = BufReader :: new ( stdout) ;
46
+ for line in reader. lines ( ) . filter_map ( |line| line. ok ( ) ) {
47
+ //TODO: handle publish error
48
+ let _ = connection. publish_response (
49
+ & publish_topic, ResponseMessage :: Ok { request_id : request_id. clone ( ) , data : line, seq : seq, pid : pid} ) . await ;
50
+ seq +=1 ;
54
51
}
55
52
}
56
- Err ( e ) => {
57
- let _ = self . connection . publish_response ( & self . publish_topic , ResponseMessage :: Err { request_id : request_id . clone ( ) , message : format ! ( "{}" , e ) } ) . await ;
58
- }
53
+ }
54
+ Err ( e ) => {
55
+ let _ = connection . publish_response ( & publish_topic , ResponseMessage :: Err { request_id : request_id . clone ( ) , message : format ! ( "{}" , e ) } ) . await ;
59
56
}
60
57
}
61
58
}
62
59
}
63
60
}
61
+ pub async fn run ( & mut self , _shutdown_rx : broadcast:: Receiver < bool > ) {
62
+ while let Ok ( ( _, cmd) ) = self . cmd_rx . recv ( ) . await {
63
+ info ! ( "begin to handle cmd: {:?}" , & cmd) ;
64
+ let connection = self . connection . clone ( ) ;
65
+ let publish_topic = self . publish_topic . clone ( ) ;
66
+ tokio:: spawn ( async move {
67
+ Self :: run_command ( connection, cmd, publish_topic) . await ;
68
+ } ) ;
69
+ }
70
+ }
64
71
}
65
72
66
73
#[ cfg( test) ]
0 commit comments