@@ -167,6 +167,52 @@ async fn postgres_cancel_token() {
167
167
}
168
168
}
169
169
170
+ #[ cfg( feature = "mysql" ) ]
171
+ #[ tokio:: test]
172
+ async fn mysql_cancel_token ( ) {
173
+ use diesel:: result:: { DatabaseErrorKind , Error } ;
174
+ use std:: time:: Duration ;
175
+
176
+ let ( sender, receiver) = tokio:: sync:: oneshot:: channel ( ) ;
177
+
178
+ // execute a long-running query in a separate future
179
+ let query_future = async move {
180
+ let conn = & mut connection ( ) . await ;
181
+ let token = conn. cancel_token ( ) ;
182
+
183
+ // send the token back to the main thread via a oneshot channel
184
+ sender
185
+ . send ( token)
186
+ . unwrap_or_else ( |_| panic ! ( "couldn't send token" ) ) ;
187
+
188
+ diesel:: dsl:: sql :: < diesel:: sql_types:: Integer > ( "SELECT SLEEP(5)" )
189
+ . get_result :: < i32 > ( conn)
190
+ . await
191
+ } ;
192
+ let cancel_future = async move {
193
+ // wait for the cancellation token to be sent
194
+ if let Ok ( token) = receiver. await {
195
+ // give the query time to start before invoking the token
196
+ tokio:: time:: sleep ( Duration :: from_millis ( 500 ) ) . await ;
197
+ token. cancel_query ( ) . await . unwrap ( ) ;
198
+ } else {
199
+ panic ! ( "Failed to receive cancel token" ) ;
200
+ }
201
+ } ;
202
+
203
+ let ( task, _) = tokio:: join!( query_future, cancel_future) ;
204
+
205
+ // make sure the query task resulted in a cancellation error or a return value of 1:
206
+ match task {
207
+ Err ( Error :: DatabaseError ( DatabaseErrorKind :: Unknown , v) )
208
+ if v. message ( ) == "Query execution was interrupted" => { }
209
+ Err ( e) => panic ! ( "unexpected error: {:?}" , e) ,
210
+ // mysql 8.4 returns 1 from a canceled sleep instead of an error
211
+ Ok ( 1 ) => { }
212
+ Ok ( _) => panic ! ( "query completed successfully without cancellation" ) ,
213
+ }
214
+ }
215
+
170
216
#[ cfg( feature = "postgres" ) ]
171
217
async fn setup ( connection : & mut TestConnection ) {
172
218
diesel:: sql_query (
0 commit comments