Skip to content

Commit 58e2f45

Browse files
committed
Merge remote-tracking branch 'origin/candidate-9.4.x' into candidate-9.6.x
Signed-off-by: Jake Smith <[email protected]> # Conflicts: # commons-hpcc/pom.xml # dfsclient/pom.xml # pom.xml # wsclient/pom.xml
2 parents 373ca84 + a87e953 commit 58e2f45

File tree

2 files changed

+110
-23
lines changed

2 files changed

+110
-23
lines changed

dfsclient/src/main/java/org/hpccsystems/dfs/client/FileUtility.java

+17-8
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public class FileUtility
6464
private static final int DEFAULT_SPLIT_TABLE_SIZE = 128;
6565

6666
private static final int NUM_DEFAULT_THREADS = 4;
67+
static private final int DEFAULT_ACCESS_EXPIRY_SECONDS = 120;
6768

6869
private static class TaskContext
6970
{
@@ -425,6 +426,7 @@ private static Options getReadTestOptions()
425426
options.addOption("user", true, "Specifies the username used to connect. Defaults to null.");
426427
options.addOption("pass", true, "Specifies the password used to connect. Defaults to null.");
427428
options.addOption("num_threads", true, "Specifies the number of parallel to use to perform operations.");
429+
options.addOption("access_expiry_seconds", true, "Access token expiration seconds.");
428430

429431
options.addOption(Option.builder("file_parts")
430432
.argName("_file_parts")
@@ -633,11 +635,6 @@ private static String[] filterFilesByFormat(String[] srcFiles, FileFormat format
633635

634636
private static void executeTasks(Runnable[] tasks, int numThreads) throws Exception
635637
{
636-
if (tasks.length > numThreads)
637-
{
638-
numThreads = tasks.length;
639-
}
640-
641638
int numTasksPerThread = tasks.length / numThreads;
642639
int numResidualTasks = tasks.length % numThreads;
643640

@@ -686,16 +683,15 @@ private static Runnable[] createReadTestTasks(DataPartition[] fileParts, FieldDe
686683
{
687684
final int taskIndex = i;
688685
final DataPartition filePart = fileParts[taskIndex];
689-
final HpccRemoteFileReader<HPCCRecord> filePartReader = new HpccRemoteFileReader<HPCCRecord>(filePart, recordDef, new HPCCRecordBuilder(recordDef));
690686

691687
tasks[taskIndex] = new Runnable()
692688
{
693-
HpccRemoteFileReader<HPCCRecord> fileReader = filePartReader;
694-
695689
public void run()
696690
{
697691
try
698692
{
693+
HpccRemoteFileReader<HPCCRecord> fileReader = new HpccRemoteFileReader<HPCCRecord>(filePart, recordDef, new HPCCRecordBuilder(recordDef));
694+
699695
while (fileReader.hasNext())
700696
{
701697
HPCCRecord record = fileReader.next();
@@ -1250,6 +1246,18 @@ private static void performReadTest(String[] args, TaskContext context)
12501246
+ numThreadsStr + ", must be an integer. Defaulting to: " + NUM_DEFAULT_THREADS + " threads.");
12511247
}
12521248

1249+
int expirySeconds = DEFAULT_ACCESS_EXPIRY_SECONDS;
1250+
String expirySecondsStr = cmd.getOptionValue("access_expiry_seconds", "" + expirySeconds);
1251+
try
1252+
{
1253+
expirySeconds = Integer.parseInt(expirySecondsStr);
1254+
}
1255+
catch(Exception e)
1256+
{
1257+
System.out.println("Invalid option value for access_expiry_seconds: "
1258+
+ numThreadsStr + ", must be an integer. Defaulting to: " + DEFAULT_ACCESS_EXPIRY_SECONDS + "s.");
1259+
}
1260+
12531261
String formatStr = cmd.getOptionValue("format");
12541262
if (formatStr == null)
12551263
{
@@ -1277,6 +1285,7 @@ private static void performReadTest(String[] args, TaskContext context)
12771285
try
12781286
{
12791287
file = new HPCCFile(datasetName, connString, user, pass);
1288+
file.setFileAccessExpirySecs(expirySeconds);
12801289
}
12811290
catch (Exception e)
12821291
{

dfsclient/src/main/java/org/hpccsystems/dfs/client/HpccRemoteFileReader.java

+93-15
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,20 @@ public class HpccRemoteFileReader<T> implements Iterator<T>
3838
private boolean handlePrefetch = true;
3939
private boolean isClosed = false;
4040
private boolean canReadNext = true;
41+
private boolean createPrefetchThread = true;
42+
private int retryCount = 0;
43+
private int connectTimeout = 0;
44+
private int readSizeKB = 0;
45+
private int limit = -1;
46+
private int maxReadRetries = DEFAULT_READ_RETRIES;
47+
private int socketOpTimeoutMs = 0;
4148
private long openTimeMs = 0;
4249
private long recordsRead = 0;
4350

4451
public static final int NO_RECORD_LIMIT = -1;
4552
public static final int DEFAULT_READ_SIZE_OPTION = -1;
4653
public static final int DEFAULT_CONNECT_TIMEOUT_OPTION = -1;
54+
public static final int DEFAULT_READ_RETRIES = 3;
4755

4856
public static class FileReadResumeInfo
4957
{
@@ -189,18 +197,23 @@ public HpccRemoteFileReader(DataPartition dp, FieldDef originalRD, IRecordBuilde
189197
{
190198
this.handlePrefetch = createPrefetchThread;
191199
this.originalRecordDef = originalRD;
192-
if (this.originalRecordDef == null)
193-
{
194-
throw new Exception("HpccRemoteFileReader: Original record definition is null.");
195-
}
200+
this.dataPartition = dp;
201+
this.recordBuilder = recBuilder;
202+
this.readSizeKB = readSizeKB;
203+
this.limit = limit;
204+
this.createPrefetchThread = createPrefetchThread;
205+
this.socketOpTimeoutMs = socketOpTimeoutMs;
196206

197207
if (connectTimeout < 1)
198208
{
199209
connectTimeout = RowServiceInputStream.DEFAULT_CONNECT_TIMEOUT_MILIS;
200210
}
211+
this.connectTimeout = connectTimeout;
201212

202-
this.dataPartition = dp;
203-
this.recordBuilder = recBuilder;
213+
if (this.originalRecordDef == null)
214+
{
215+
throw new Exception("HpccRemoteFileReader: Provided original record definition is null, original record definition is required.");
216+
}
204217

205218
FieldDef projectedRecordDefinition = recBuilder.getRecordDefinition();
206219
if (projectedRecordDefinition == null)
@@ -246,6 +259,61 @@ public HpccRemoteFileReader(DataPartition dp, FieldDef originalRD, IRecordBuilde
246259
openTimeMs = System.currentTimeMillis();
247260
}
248261

262+
private boolean retryRead()
263+
{
264+
if (retryCount < maxReadRetries)
265+
{
266+
log.info("Retrying read for " + this.dataPartition.toString() + " retry count: " + retryCount);
267+
retryCount++;
268+
269+
FileReadResumeInfo resumeInfo = getFileReadResumeInfo();
270+
RowServiceInputStream.RestartInformation restartInfo = new RowServiceInputStream.RestartInformation();
271+
restartInfo.streamPos = resumeInfo.inputStreamPos;
272+
restartInfo.tokenBin = resumeInfo.tokenBin;
273+
274+
try
275+
{
276+
this.inputStream.close();
277+
}
278+
catch (Exception e) {}
279+
280+
try
281+
{
282+
this.inputStream = new RowServiceInputStream(this.dataPartition, this.originalRecordDef,
283+
this.recordBuilder.getRecordDefinition(), this.connectTimeout, this.limit, this.createPrefetchThread,
284+
this.readSizeKB, restartInfo, false, this.socketOpTimeoutMs);
285+
long bytesToSkip = resumeInfo.recordReaderStreamPos - resumeInfo.inputStreamPos;
286+
if (bytesToSkip < 0)
287+
{
288+
throw new Exception("Unable to restart read stream, unexpected stream position in record reader.");
289+
}
290+
this.inputStream.skip(bytesToSkip);
291+
292+
this.binaryRecordReader = new BinaryRecordReader(this.inputStream, resumeInfo.recordReaderStreamPos);
293+
this.binaryRecordReader.initialize(this.recordBuilder);
294+
}
295+
catch (Exception e)
296+
{
297+
log.error("Failed to retry read for " + this.dataPartition.toString() + " " + e.getMessage(), e);
298+
return false;
299+
}
300+
301+
return true;
302+
}
303+
304+
return false;
305+
}
306+
307+
/**
308+
* Sets the maximum number of times to retry a read operation before failing.
309+
*
310+
* @param maxReadRetries maximum number of read retries
311+
*/
312+
public void setMaxReadRetries(int maxReadRetries)
313+
{
314+
this.maxReadRetries = maxReadRetries;
315+
}
316+
249317
/**
250318
* Returns the stream position within the file.
251319
*
@@ -363,11 +431,16 @@ public boolean hasNext()
363431
}
364432
catch (HpccFileException e)
365433
{
366-
canReadNext = false;
367-
log.error("Read failure for " + this.dataPartition.toString());
368-
java.util.NoSuchElementException exception = new java.util.NoSuchElementException("Fatal read error: " + e.getMessage());
369-
exception.initCause(e);
370-
throw exception;
434+
if (!retryRead())
435+
{
436+
canReadNext = false;
437+
log.error("Read failure for " + this.dataPartition.toString(), e);
438+
java.util.NoSuchElementException exception = new java.util.NoSuchElementException("Fatal read error: " + e.getMessage());
439+
exception.initCause(e);
440+
throw exception;
441+
}
442+
443+
return hasNext();
371444
}
372445

373446
return canReadNext;
@@ -393,10 +466,15 @@ public T next()
393466
}
394467
catch (HpccFileException e)
395468
{
396-
log.error("Read failure for " + this.dataPartition.toString() + " " + e.getMessage());
397-
java.util.NoSuchElementException exception = new java.util.NoSuchElementException("Fatal read error: " + e.getMessage());
398-
exception.initCause(e);
399-
throw exception;
469+
if (!retryRead())
470+
{
471+
log.error("Read failure for " + this.dataPartition.toString() + " " + e.getMessage(), e);
472+
java.util.NoSuchElementException exception = new java.util.NoSuchElementException("Fatal read error: " + e.getMessage());
473+
exception.initCause(e);
474+
throw exception;
475+
}
476+
477+
return next();
400478
}
401479

402480
recordsRead++;

0 commit comments

Comments
 (0)