@@ -167,6 +167,52 @@ async fn postgres_cancel_token() {
167167 }
168168}
169169
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+
170216#[ cfg( feature = "postgres" ) ]
171217async fn setup ( connection : & mut TestConnection ) {
172218 diesel:: sql_query (
0 commit comments