@@ -37,13 +37,8 @@ pub struct Client {
37
37
macro_rules! impl_inner_call {
38
38
( $self: expr, $name: ident $( , $args: expr) * ) => {
39
39
{
40
- let mut count = 0 ;
41
- let mut errors = Vec :: with_capacity( count as usize ) ;
40
+ let mut errors = vec![ ] ;
42
41
loop {
43
- if count == $self. config. retry( ) {
44
- return Err ( Error :: AllAttemptsErrored ( errors) ) ;
45
- }
46
- count += 1 ;
47
42
let read_client = $self. client_type. read( ) . unwrap( ) ;
48
43
let res = match & * read_client {
49
44
ClientType :: TCP ( inner) => inner. $name( $( $args, ) * ) ,
@@ -53,32 +48,40 @@ macro_rules! impl_inner_call {
53
48
drop( read_client) ;
54
49
match res {
55
50
Ok ( val) => return Ok ( val) ,
56
- Err ( Error :: Protocol ( e) ) => {
57
- warn!( "Error::Protocol {:?}" , e) ;
58
- continue
51
+ Err ( Error :: Protocol ( _) ) => {
52
+ return res;
59
53
} ,
60
54
Err ( e) => {
61
- match $self. client_type. try_write( ) {
62
- Ok ( mut write_client) => {
63
- warn!( "retry:{}/{} {:?}" , count, $self. config. retry( ) , e) ;
64
- errors. push( e) ;
55
+ warn!( "call retry:{}/{} {:?}" , errors. len( ) + 1 , $self. config. retry( ) , e) ;
56
+ errors. push( e) ;
57
+ if errors. len( ) as u8 == $self. config. retry( ) {
58
+ return Err ( Error :: AllAttemptsErrored ( errors) ) ;
59
+ }
60
+
61
+ // Only one thread will try to recreate the client getting the write lock,
62
+ // other eventual threads will get Err and will block at the beginning of
63
+ // previous loop when trying to read()
64
+ if let Ok ( mut write_client) = $self. client_type. try_write( ) {
65
+ loop {
66
+ std:: thread:: sleep( std:: time:: Duration :: from_secs( errors. len( ) as u64 ) ) ;
65
67
match ClientType :: from_config( & $self. url, & $self. config) {
66
68
Ok ( new_client) => {
67
69
info!( "Succesfully created new client" ) ;
68
70
* write_client = new_client;
71
+ break ;
69
72
} ,
70
73
Err ( e) => {
71
- warn!( "Cannot create new client {:?}" , e) ;
74
+ warn!( "client retry:{}/{} {:?}" , errors. len( ) + 1 , $self. config. retry( ) , e) ;
75
+ errors. push( e) ;
76
+ if errors. len( ) as u8 == $self. config. retry( ) {
77
+ return Err ( Error :: AllAttemptsErrored ( errors) ) ;
78
+ }
72
79
}
73
80
}
74
-
75
- } ,
76
- Err ( _) => ( ) , // another thread is trying to retrying the client
81
+ }
77
82
}
78
83
} ,
79
84
}
80
-
81
- std:: thread:: sleep( std:: time:: Duration :: from_secs( count as u64 ) ) ;
82
85
} }
83
86
}
84
87
}
0 commit comments