Skip to content

Commit 52606c2

Browse files
Allow per-filesystem specification of channel reopen count
1 parent 919e67b commit 52606c2

3 files changed

Lines changed: 24 additions & 8 deletions

File tree

google-cloud-contrib/google-cloud-nio/src/main/java/com/google/cloud/storage/contrib/nio/CloudStorageConfiguration.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ public abstract class CloudStorageConfiguration {
5959
*/
6060
public abstract int blockSize();
6161

62+
/**
63+
* Returns the number of times we try re-opening a channel if it's closed unexpectedly
64+
* while reading.
65+
*/
66+
public abstract int channelReopen();
67+
6268
/**
6369
* Creates a new builder, initialized with the following settings:
6470
*
@@ -82,6 +88,7 @@ public static final class Builder {
8288
private boolean stripPrefixSlash = true;
8389
private boolean usePseudoDirectories = true;
8490
private int blockSize = CloudStorageFileSystem.BLOCK_SIZE_DEFAULT;
91+
private int channelReopen = 0;
8592

8693
/**
8794
* Changes current working directory for new filesystem. This defaults to the root directory.
@@ -134,6 +141,11 @@ public Builder blockSize(int value) {
134141
return this;
135142
}
136143

144+
public Builder channelReopen(int value) {
145+
channelReopen = value;
146+
return this;
147+
}
148+
137149
/**
138150
* Creates new instance without destroying builder.
139151
*/
@@ -143,7 +155,8 @@ public CloudStorageConfiguration build() {
143155
permitEmptyPathComponents,
144156
stripPrefixSlash,
145157
usePseudoDirectories,
146-
blockSize);
158+
blockSize,
159+
channelReopen);
147160
}
148161

149162
Builder() {}
@@ -168,6 +181,9 @@ static CloudStorageConfiguration fromMap(Map<String, ?> env) {
168181
case "blockSize":
169182
builder.blockSize((Integer) entry.getValue());
170183
break;
184+
case "channelReopen":
185+
builder.channelReopen((Integer) entry.getValue());
186+
break;
171187
default:
172188
throw new IllegalArgumentException(entry.getKey());
173189
}

google-cloud-contrib/google-cloud-nio/src/main/java/com/google/cloud/storage/contrib/nio/CloudStorageFileSystemProvider.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ public CloudStorageFileSystemProvider() {
139139

140140
CloudStorageFileSystemProvider(@Nullable StorageOptions gcsStorageOptions) {
141141
this.storageOptions = gcsStorageOptions;
142-
143142
}
144143

145144
// Initialize this.storage, once. This may throw an exception if default authentication
@@ -226,7 +225,7 @@ public SeekableByteChannel newByteChannel(
226225
private SeekableByteChannel newReadChannel(Path path, Set<? extends OpenOption> options)
227226
throws IOException {
228227
initStorage();
229-
int channelReopen = 0;
228+
int channelReopen = ((CloudStorageFileSystem)path.getFileSystem()).config().channelReopen();
230229
for (OpenOption option : options) {
231230
if (option instanceof StandardOpenOption) {
232231
switch ((StandardOpenOption) option) {

google-cloud-contrib/google-cloud-nio/src/main/java/com/google/cloud/storage/contrib/nio/CloudStorageReadChannel.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ final class CloudStorageReadChannel implements SeekableByteChannel {
4444

4545
private final Storage gcsStorage;
4646
private final BlobId file;
47-
private ReadChannel channel;
48-
private long position;
49-
private long size;
5047
// max # of times we may reopen the file
5148
private final int maxReopen;
5249
// how many times we re-opened the file
5350
private int reopens;
51+
private ReadChannel channel;
52+
private long position;
53+
private long size;
5454

5555
/**
5656
* @param maxReopen max. number of times to try re-opening the channel if it closes on us unexpectedly.
@@ -66,6 +66,7 @@ private CloudStorageReadChannel(Storage gcsStorage, BlobId file, long position,
6666
this.gcsStorage = gcsStorage;
6767
this.file = file;
6868
this.position = position;
69+
this.reopens = 0;
6970
this.maxReopen = maxReopen;
7071
// XXX: Reading size and opening file should be atomic.
7172
this.size = fetchSize(gcsStorage, file);
@@ -107,9 +108,9 @@ public int read(ByteBuffer dst) throws IOException {
107108
amt = channel.read(dst);
108109
break;
109110
} catch (StorageException exs) {
110-
// this error isn't marked as retryable since the channel is closed;
111-
// but here at this higher level we can retry it.
112111
if (exs.getMessage().contains("Connection closed prematurely") && reopens < maxReopen) {
112+
// this error isn't marked as retryable since the channel is closed;
113+
// but here at this higher level we can retry it.
113114
reopens++;
114115
retryDelay(reopens);
115116
innerOpen();

0 commit comments

Comments
 (0)