1
- use anyhow:: { Context , Error } ;
1
+ use anyhow:: { anyhow , Context } ;
2
2
use std:: net:: SocketAddr ;
3
3
use std:: sync:: Arc ;
4
4
use tokio:: {
@@ -10,6 +10,7 @@ use tokio::{
10
10
runtime:: Runtime ,
11
11
sync:: broadcast:: Sender ,
12
12
} ;
13
+ use tracing:: error;
13
14
use url:: Url ;
14
15
15
16
pub ( crate ) struct ChaosProxy {
@@ -23,7 +24,7 @@ pub(crate) struct ChaosProxy {
23
24
}
24
25
25
26
impl ChaosProxy {
26
- pub ( crate ) fn new ( backend_address : SocketAddr ) -> Result < Arc < Self > , Error > {
27
+ pub ( crate ) fn new ( backend_address : SocketAddr ) -> anyhow :: Result < Arc < Self > > {
27
28
let runtime = Runtime :: new ( ) . expect ( "failed to create Tokio runtime" ) ;
28
29
let listener = runtime. block_on ( TcpListener :: bind ( "127.0.0.1:0" ) ) ?;
29
30
@@ -42,42 +43,49 @@ impl ChaosProxy {
42
43
43
44
let instance_clone = instance. clone ( ) ;
44
45
instance. runtime . spawn ( async move {
45
- if let Err ( err ) = instance_clone. server_loop ( listener) . await {
46
- eprintln ! ( "ChaosProxy server error: {err} " ) ;
46
+ if let Err ( error ) = instance_clone. server_loop ( listener) . await {
47
+ error ! ( %error , "ChaosProxy server error" ) ;
47
48
}
48
49
} ) ;
49
50
50
51
Ok ( instance)
51
52
}
52
53
53
- pub ( crate ) fn proxy_database_url ( url : & str ) -> Result < ( Arc < Self > , String ) , Error > {
54
+ pub ( crate ) fn proxy_database_url ( url : & str ) -> anyhow :: Result < ( Arc < Self > , String ) > {
54
55
let mut db_url = Url :: parse ( url) . context ( "failed to parse database url" ) ?;
55
56
let backend_addr = db_url
56
57
. socket_addrs ( || Some ( 5432 ) )
57
58
. context ( "could not resolve database url" ) ?
58
59
. first ( )
59
60
. copied ( )
60
- . ok_or_else ( || anyhow:: anyhow!( "the database url does not point to any IP" ) ) ?;
61
+ . ok_or_else ( || anyhow ! ( "the database url does not point to any IP" ) ) ?;
62
+
63
+ let instance = ChaosProxy :: new ( backend_addr) ?;
64
+
65
+ db_url
66
+ . set_ip_host ( instance. address . ip ( ) )
67
+ . map_err ( |_| anyhow ! ( "Failed to set IP host on the URL" ) ) ?;
68
+
69
+ db_url
70
+ . set_port ( Some ( instance. address . port ( ) ) )
71
+ . map_err ( |_| anyhow ! ( "Failed to set post on the URL" ) ) ?;
61
72
62
- let instance = ChaosProxy :: new ( backend_addr) . unwrap ( ) ;
63
- db_url. set_ip_host ( instance. address . ip ( ) ) . unwrap ( ) ;
64
- db_url. set_port ( Some ( instance. address . port ( ) ) ) . unwrap ( ) ;
65
73
Ok ( ( instance, db_url. into ( ) ) )
66
74
}
67
75
68
- pub ( crate ) fn break_networking ( & self ) {
76
+ pub ( crate ) fn break_networking ( & self ) -> anyhow :: Result < usize > {
69
77
self . break_networking_send
70
78
. send ( ( ) )
71
- . expect ( "failed to send the break_networking message") ;
79
+ . context ( "Failed to send the break_networking message")
72
80
}
73
81
74
- pub ( crate ) fn restore_networking ( & self ) {
82
+ pub ( crate ) fn restore_networking ( & self ) -> anyhow :: Result < usize > {
75
83
self . restore_networking_send
76
84
. send ( ( ) )
77
- . expect ( "failed to send the restore_networking message") ;
85
+ . context ( "Failed to send the restore_networking message")
78
86
}
79
87
80
- async fn server_loop ( self : Arc < Self > , initial_listener : TcpListener ) -> Result < ( ) , Error > {
88
+ async fn server_loop ( & self , initial_listener : TcpListener ) -> anyhow :: Result < ( ) > {
81
89
let mut listener = Some ( initial_listener) ;
82
90
83
91
let mut break_networking_recv = self . break_networking_send . subscribe ( ) ;
@@ -87,7 +95,7 @@ impl ChaosProxy {
87
95
if let Some ( l) = & listener {
88
96
tokio:: select! {
89
97
accepted = l. accept( ) => {
90
- self . clone ( ) . accept_connection( accepted?. 0 ) . await ?;
98
+ self . accept_connection( accepted?. 0 ) . await ?;
91
99
} ,
92
100
93
101
_ = break_networking_recv. recv( ) => {
@@ -104,51 +112,53 @@ impl ChaosProxy {
104
112
}
105
113
}
106
114
107
- async fn accept_connection ( self : Arc < Self > , accepted : TcpStream ) -> Result < ( ) , Error > {
115
+ async fn accept_connection ( & self , accepted : TcpStream ) -> anyhow :: Result < ( ) > {
108
116
let ( client_read, client_write) = accepted. into_split ( ) ;
109
117
let ( backend_read, backend_write) = TcpStream :: connect ( & self . backend_address )
110
118
. await ?
111
119
. into_split ( ) ;
112
120
113
- let self_clone = self . clone ( ) ;
121
+ let break_networking_send = self . break_networking_send . clone ( ) ;
114
122
tokio:: spawn ( async move {
115
- if let Err ( err) = self_clone. proxy_data ( client_read, backend_write) . await {
116
- eprintln ! ( "ChaosProxy connection error: {err}" ) ;
123
+ if let Err ( error) = proxy_data ( break_networking_send, client_read, backend_write) . await
124
+ {
125
+ error ! ( %error, "ChaosProxy connection error" ) ;
117
126
}
118
127
} ) ;
119
128
120
- let self_clone = self . clone ( ) ;
129
+ let break_networking_send = self . break_networking_send . clone ( ) ;
121
130
tokio:: spawn ( async move {
122
- if let Err ( err) = self_clone. proxy_data ( backend_read, client_write) . await {
123
- eprintln ! ( "ChaosProxy connection error: {err}" ) ;
131
+ if let Err ( error) = proxy_data ( break_networking_send, backend_read, client_write) . await
132
+ {
133
+ error ! ( %error, "ChaosProxy connection error" ) ;
124
134
}
125
135
} ) ;
126
136
127
137
Ok ( ( ) )
128
138
}
139
+ }
129
140
130
- async fn proxy_data (
131
- & self ,
132
- mut from : OwnedReadHalf ,
133
- mut to : OwnedWriteHalf ,
134
- ) -> Result < ( ) , Error > {
135
- let mut break_connections_recv = self . break_networking_send . subscribe ( ) ;
136
- let mut buf = [ 0 ; 1024 ] ;
137
-
138
- loop {
139
- tokio:: select! {
140
- len = from. read( & mut buf) => {
141
- let len = len?;
142
- if len == 0 {
143
- // EOF, the socket was closed
144
- return Ok ( ( ) ) ;
145
- }
146
- to. write_all( & buf[ 0 ..len] ) . await ?;
147
- }
148
- _ = break_connections_recv. recv( ) => {
149
- to. shutdown( ) . await ?;
141
+ async fn proxy_data (
142
+ break_networking_send : Sender < ( ) > ,
143
+ mut from : OwnedReadHalf ,
144
+ mut to : OwnedWriteHalf ,
145
+ ) -> anyhow:: Result < ( ) > {
146
+ let mut break_connections_recv = break_networking_send. subscribe ( ) ;
147
+ let mut buf = [ 0 ; 1024 ] ;
148
+
149
+ loop {
150
+ tokio:: select! {
151
+ len = from. read( & mut buf) => {
152
+ let len = len?;
153
+ if len == 0 {
154
+ // EOF, the socket was closed
150
155
return Ok ( ( ) ) ;
151
156
}
157
+ to. write_all( & buf[ 0 ..len] ) . await ?;
158
+ }
159
+ _ = break_connections_recv. recv( ) => {
160
+ to. shutdown( ) . await ?;
161
+ return Ok ( ( ) ) ;
152
162
}
153
163
}
154
164
}
0 commit comments