From 23cf258047f4391161b188ba520ca0b0929bb637 Mon Sep 17 00:00:00 2001 From: Gregory Michael Travis Date: Wed, 18 Dec 2024 13:24:48 -0500 Subject: [PATCH] Clear excel cache on reload (#11872) (cherry picked from commit 7d3293cf4a1ff3a7467d74671d4594d343817c8e) --- .../org/enso/base/cache/ReloadDetector.java | 2 +- .../enso/table/excel/ExcelConnectionPool.java | 26 +++++++++++++++++++ test/Table_Tests/src/IO/Excel_Spec.enso | 21 +++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/std-bits/base/src/main/java/org/enso/base/cache/ReloadDetector.java b/std-bits/base/src/main/java/org/enso/base/cache/ReloadDetector.java index 5328c8003a16..d1f308353cd8 100644 --- a/std-bits/base/src/main/java/org/enso/base/cache/ReloadDetector.java +++ b/std-bits/base/src/main/java/org/enso/base/cache/ReloadDetector.java @@ -32,7 +32,7 @@ private void resetEnsoReloadDetector() { "Standard.Base.Network.Reload_Detector", "create_reload_detector"); } - void simulateReloadTestOnly() { + public void simulateReloadTestOnly() { EnsoMeta.callStaticModuleMethod( "Standard.Base.Network.Reload_Detector", "simulate_reload_test_only", ensoReloadDetector); } diff --git a/std-bits/table/src/main/java/org/enso/table/excel/ExcelConnectionPool.java b/std-bits/table/src/main/java/org/enso/table/excel/ExcelConnectionPool.java index 92f4db31721a..af8a43263ac3 100644 --- a/std-bits/table/src/main/java/org/enso/table/excel/ExcelConnectionPool.java +++ b/std-bits/table/src/main/java/org/enso/table/excel/ExcelConnectionPool.java @@ -20,6 +20,7 @@ import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.enso.base.cache.ReloadDetector; import org.enso.table.excel.xssfreader.XSSFReaderWorkbook; public class ExcelConnectionPool { @@ -36,6 +37,8 @@ public ReadOnlyExcelConnection openReadOnlyConnection(File file, ExcelFileFormat + "written to. This is a bug in the Table library."); } + clearOnReload(); + if (!file.exists()) { throw new FileNotFoundException(file.toString()); } @@ -209,6 +212,29 @@ void release(ReadOnlyExcelConnection excelConnection) throws IOException { private final HashMap records = new HashMap<>(); private boolean isCurrentlyWriting = false; + /** Used to clear the ConnectionRecord on reload. */ + private final ReloadDetector reloadDetector = new ReloadDetector(); + + /** If a reload has just happened, clear the ConnectionRecord cache. */ + private void clearOnReload() throws IOException { + if (reloadDetector.hasReloadOccurred()) { + for (var record : records.values()) { + record.close(); + } + records.clear(); + } + } + + /** Public for testing. */ + public int getConnectionRecordCount() { + return records.size(); + } + + /** Public for testing. */ + public void simulateReloadTestOnly() { + reloadDetector.simulateReloadTestOnly(); + } + static class ConnectionRecord { private int refCount; private File file; diff --git a/test/Table_Tests/src/IO/Excel_Spec.enso b/test/Table_Tests/src/IO/Excel_Spec.enso index eb87b1bb5968..9e3f417ab1e0 100644 --- a/test/Table_Tests/src/IO/Excel_Spec.enso +++ b/test/Table_Tests/src/IO/Excel_Spec.enso @@ -24,6 +24,7 @@ from project.Common_Table_Operations.Util import within_table from project.IO.Read_Many_Spec import with_temp_dir polyglot java import org.enso.table_test_helpers.RandomHelpers +polyglot java import org.enso.table.excel.ExcelConnectionPool spec_fmt suite_builder header file read_method sheet_count=5 = suite_builder.group header group_builder-> @@ -1151,6 +1152,26 @@ add_specs suite_builder = r3.at "Value" . at 0 . should_be_a Table r3.at "Value" . at 1 . should_be_a Excel_Workbook + group_builder.specify "should clear cache on simulated reload" <| + ExcelConnectionPool.INSTANCE.simulateReloadTestOnly + check_workbook <| xlsx_sheet.read + ExcelConnectionPool.INSTANCE.getConnectionRecordCount . should_equal 1 + check_workbook <| xlsx_sheet.read + ExcelConnectionPool.INSTANCE.getConnectionRecordCount . should_equal 1 + check_workbook <| xls_sheet.read + ExcelConnectionPool.INSTANCE.getConnectionRecordCount . should_equal 2 + check_workbook <| xls_sheet.read + ExcelConnectionPool.INSTANCE.getConnectionRecordCount . should_equal 2 + ExcelConnectionPool.INSTANCE.simulateReloadTestOnly + check_workbook <| xlsx_sheet.read + ExcelConnectionPool.INSTANCE.getConnectionRecordCount . should_equal 1 + check_workbook <| xlsx_sheet.read + ExcelConnectionPool.INSTANCE.getConnectionRecordCount . should_equal 1 + check_workbook <| xls_sheet.read + ExcelConnectionPool.INSTANCE.getConnectionRecordCount . should_equal 2 + check_workbook <| xls_sheet.read + ExcelConnectionPool.INSTANCE.getConnectionRecordCount . should_equal 2 + suite_builder.group "Problems" group_builder-> group_builder.specify "should report a user-friendly error message when format is missing a required argument" <| r = xlsx_sheet.read (..Range)