Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import static org.apache.paimon.rest.RESTApi.TOKEN_EXPIRATION_SAFE_TIME_MILLIS;
import static org.apache.paimon.rest.RESTCatalogOptions.DLF_OSS_ENDPOINT;
import static org.apache.paimon.rest.RESTCatalogOptions.IO_CACHE_ENABLED;
import static org.apache.paimon.utils.Preconditions.checkArgument;

/** A {@link FileIO} to support getting token from REST Server. */
public class RESTTokenFileIO implements FileIO {
Expand Down Expand Up @@ -82,6 +83,24 @@ public class RESTTokenFileIO implements FileIO {

private static final Logger LOG = LoggerFactory.getLogger(RESTTokenFileIO.class);

/** Sets the maximum number of cached FileIO instances. */
public static void setFileIOCacheMaximumSize(long maximumSize) {
checkArgument(maximumSize > 0, "Maximum cache size must be positive.");
FILE_IO_CACHE
.policy()
.eviction()
.orElseThrow(IllegalStateException::new)
.setMaximum(maximumSize);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Do not accept a zero cache size with the current ownership model

The new test explicitly makes 0 a supported value, but this cache owns its values: its removal listener closes every evicted FileIO. With a Caffeine maximum of zero, fileIO() creates an instance, puts it into FILE_IO_CACHE, and it is immediately eligible for SIZE eviction/close even though the method then returns that same instance to the current operation. An application using the conventional 0 = disable caching setting can therefore get a closed FileIO during newInputStream, newOutputStream, etc., reproducing the premature-close failure this change is intended to mitigate.

Please either require maximumSize > 0, or implement an explicit no-cache path whose FileIO lifetime extends through the operation instead of inserting it into this owning cache.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in ec3d312. The setter now requires maximumSize > 0, and the test covers the zero value.

}

static long fileIOCacheMaximumSize() {
return FILE_IO_CACHE
.policy()
.eviction()
.orElseThrow(IllegalStateException::new)
.getMaximum();
}

private final CatalogContext catalogContext;
private final Identifier identifier;
private final Path path;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,20 @@
/** Tests for {@link RESTTokenFileIO}. */
class RESTTokenFileIOTest {

@Test
void testSetFileIOCacheMaximumSize() {
long originalMaximumSize = RESTTokenFileIO.fileIOCacheMaximumSize();
try {
RESTTokenFileIO.setFileIOCacheMaximumSize(2000);
assertThat(RESTTokenFileIO.fileIOCacheMaximumSize()).isEqualTo(2000);
assertThatThrownBy(() -> RESTTokenFileIO.setFileIOCacheMaximumSize(0))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Maximum cache size must be positive.");
} finally {
RESTTokenFileIO.setFileIOCacheMaximumSize(originalMaximumSize);
}
}

@Test
void testCreateBlobPresignedUrlRequiresBoundRootAndDelegates() throws IOException {
Path tableRoot = new Path("oss://bucket/table");
Expand Down
Loading