7
7
8
8
import java .io .IOException ;
9
9
import java .io .InputStream ;
10
+ import java .net .SocketException ;
11
+ import java .util .concurrent .ThreadLocalRandom ;
10
12
11
13
public class CosNFileReadTask implements Runnable {
12
14
static final Logger LOG = LoggerFactory .getLogger (CosNFileReadTask .class );
13
15
16
+ private final Configuration conf ;
14
17
private final String key ;
15
18
private final NativeFileSystemStore store ;
16
19
private final CosNFSInputStream .ReadBuffer readBuffer ;
20
+ private final int socketErrMaxRetryTimes ;
17
21
18
22
/**
19
23
* cos file read task
@@ -24,40 +28,86 @@ public class CosNFileReadTask implements Runnable {
24
28
*/
25
29
public CosNFileReadTask (Configuration conf , String key ,
26
30
NativeFileSystemStore store ,
27
- CosNFSInputStream .ReadBuffer readBuffer ) {
31
+ CosNFSInputStream .ReadBuffer readBuffer ,
32
+ int socketErrMaxRetryTimes ) {
33
+ this .conf = conf ;
28
34
this .key = key ;
29
35
this .store = store ;
30
36
this .readBuffer = readBuffer ;
37
+ this .socketErrMaxRetryTimes = socketErrMaxRetryTimes ;
31
38
}
32
39
33
40
@ Override
34
41
public void run () {
35
42
try {
36
43
this .readBuffer .lock ();
37
- try {
38
- InputStream inputStream = this .store .retrieveBlock (
39
- this .key , this .readBuffer .getStart (),
40
- this .readBuffer .getEnd ());
41
- IOUtils .readFully (
42
- inputStream , this .readBuffer .getBuffer (), 0 ,
43
- readBuffer .getBuffer ().length );
44
- int readEof = inputStream .read ();
45
- if (readEof != -1 ) {
46
- LOG .error ("Expect to read the eof, but the return is not -1. key: {}." , this .key );
44
+ int retryIndex = 1 ;
45
+ boolean needRetry = false ;
46
+ while (true ) {
47
+ try {
48
+ this .retrieveBlock ();
49
+ needRetry = false ;
50
+ } catch (SocketException se ) {
51
+ // if we get stream success, but exceptions occurs when read cos input stream
52
+ String errMsg = String .format ("retrieve block sdk socket failed, " +
53
+ "retryIndex: [%d / %d], key: %s, range: [%d , %d], exception: %s" ,
54
+ retryIndex , this .socketErrMaxRetryTimes , this .key ,
55
+ this .readBuffer .getStart (), this .readBuffer .getEnd (), se .toString ());
56
+ if (retryIndex <= this .socketErrMaxRetryTimes ) {
57
+ LOG .info (errMsg , se );
58
+ long sleepLeast = retryIndex * 300L ;
59
+ long sleepBound = retryIndex * 500L ;
60
+ try {
61
+ Thread .sleep (ThreadLocalRandom .current ().
62
+ nextLong (sleepLeast , sleepBound ));
63
+ ++retryIndex ;
64
+ needRetry = true ;
65
+ } catch (InterruptedException ie ) {
66
+ this .setFailResult (errMsg , new IOException (ie .toString ()));
67
+ break ;
68
+ }
69
+ } else {
70
+ this .setFailResult (errMsg , se );
71
+ break ;
72
+ }
73
+ } catch (IOException e ) {
74
+ String errMsg = String .format ("retrieve block sdk socket failed, " +
75
+ "retryIndex: [%d / %d], key: %s, range: [%d , %d], exception: %s" ,
76
+ retryIndex , this .socketErrMaxRetryTimes , this .key ,
77
+ this .readBuffer .getStart (), this .readBuffer .getEnd (), e .toString ());
78
+ this .setFailResult (errMsg , e );
79
+ break ;
47
80
}
48
- inputStream .close ();
49
- this .readBuffer .setStatus (CosNFSInputStream .ReadBuffer .SUCCESS );
50
- } catch (IOException e ) {
51
- this .readBuffer .setStatus (CosNFSInputStream .ReadBuffer .ERROR );
52
- this .readBuffer .setException (e );
53
- LOG .error ("Exception occurs when retrieve the block range " +
54
- "start: "
55
- + String .valueOf (this .readBuffer .getStart ()) + " " +
56
- "end: " + this .readBuffer .getEnd (), e );
57
- }
81
+
82
+ if (!needRetry ) {
83
+ break ;
84
+ }
85
+ } // end of retry
58
86
this .readBuffer .signalAll ();
59
87
} finally {
60
88
this .readBuffer .unLock ();
61
89
}
62
90
}
91
+
92
+ public void setFailResult (String msg , IOException e ) {
93
+ this .readBuffer .setStatus (CosNFSInputStream .ReadBuffer .ERROR );
94
+ this .readBuffer .setException (e );
95
+ LOG .error (msg );
96
+ }
97
+
98
+ // not thread safe
99
+ public void retrieveBlock () throws IOException {
100
+ InputStream inputStream = this .store .retrieveBlock (
101
+ this .key , this .readBuffer .getStart (),
102
+ this .readBuffer .getEnd ());
103
+ IOUtils .readFully (
104
+ inputStream , this .readBuffer .getBuffer (), 0 ,
105
+ readBuffer .getBuffer ().length );
106
+ int readEof = inputStream .read ();
107
+ if (readEof != -1 ) {
108
+ LOG .error ("Expect to read the eof, but the return is not -1. key: {}." , this .key );
109
+ }
110
+ inputStream .close ();
111
+ this .readBuffer .setStatus (CosNFSInputStream .ReadBuffer .SUCCESS );
112
+ }
63
113
}
0 commit comments