NEW: TempFileProvider will clean up files automatically if the reference is gc'ed

This commit is contained in:
Jonas Pöhler
2021-10-22 14:20:36 +02:00
parent af0f9a4d15
commit 60cf9fa078
9 changed files with 436 additions and 13 deletions
@@ -54,6 +54,7 @@ import io.ebean.config.QueryPlanCapture;
import io.ebean.config.QueryPlanListener;
import io.ebean.config.SlowQueryEvent;
import io.ebean.config.SlowQueryListener;
import io.ebean.config.TempFileProvider;
import io.ebean.config.TenantMode;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.event.BeanPersistController;
@@ -143,6 +144,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
private final String serverName;
private final DatabasePlatform databasePlatform;
private final TransactionManager transactionManager;
private final TempFileProvider tempFileProvider;
private final QueryPlanManager queryPlanManager;
private final ExtraMetrics extraMetrics;
private final DataTimeZone dataTimeZone;
@@ -223,6 +225,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
this.queryPlanManager = config.initQueryPlanManager(transactionManager);
this.metaInfoManager = new DefaultMetaInfoManager(this);
this.serverPlugins = config.getPlugins();
this.tempFileProvider = config.getConfig().getTempFileProvider();
this.ddlGenerator = config.initDdlGenerator(this);
this.scriptRunner = new DScriptRunner(this);
this.initDatabase = !config.getConfig().skipInitDatabase();
@@ -460,6 +463,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
backgroundExecutor.shutdown();
// shutdown DataSource (if its an Ebean one)
transactionManager.shutdown(shutdownDataSource, deregisterDriver);
tempFileProvider.shutdown();
dumpMetrics();
shutdown = true;
if (shutdownDataSource) {
@@ -8,6 +8,7 @@ import io.ebean.config.DatabaseConfig;
import io.ebean.config.ExternalTransactionManager;
import io.ebean.config.ProfilingConfig;
import io.ebean.config.SlowQueryListener;
import io.ebean.config.TempFileProvider;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.config.dbplatform.DbHistorySupport;
import io.ebean.event.changelog.ChangeLogListener;
@@ -75,6 +76,7 @@ public final class InternalConfiguration {
private final DatabasePlatform databasePlatform;
private final DeployInherit deployInherit;
private final TypeManager typeManager;
private final TempFileProvider tempFileProvider;
private final DtoBeanManager dtoBeanManager;
private final ClockService clockService;
private final DataTimeZone dataTimeZone;
@@ -115,6 +117,7 @@ public final class InternalConfiguration {
this.databasePlatform = config.getDatabasePlatform();
this.expressionFactory = initExpressionFactory(config);
this.typeManager = new DefaultTypeManager(config, bootupClasses);
this.tempFileProvider = config.getTempFileProvider();
this.multiValueBind = createMultiValueBind(databasePlatform.getPlatform());
this.deployInherit = new DeployInherit(bootupClasses);
this.deployCreateProperties = new DeployCreateProperties(typeManager);
@@ -511,6 +514,10 @@ public final class InternalConfiguration {
return logManager;
}
public TempFileProvider getTempFileProvider() {
return tempFileProvider;
}
private ServerCachePlugin initServerCachePlugin() {
if (config.isLocalOnlyL2Cache()) {
localL2Caching = true;
@@ -61,7 +61,7 @@ public final class DefaultTypeManager implements TypeManager {
private final DefaultTypeFactory extraTypeFactory;
private final ScalarType<?> hstoreType = new ScalarTypePostgresHstore();
private final ScalarTypeFile fileType = new ScalarTypeFile();
private final ScalarTypeFile fileType;
private final ScalarType<?> charType = new ScalarTypeChar();
private final ScalarType<?> charArrayType = new ScalarTypeCharArray();
private final ScalarType<?> longVarcharType = new ScalarTypeLongVarchar();
@@ -141,6 +141,7 @@ public final class DefaultTypeManager implements TypeManager {
this.arrayTypeSetFactory = arrayTypeSetFactory(config.getDatabasePlatform());
this.offlineMigrationGeneration = DbOffline.isGenerateMigration();
this.defaultEnumType = config.getDefaultEnumType();
this.fileType = new ScalarTypeFile(config.getTempFileProvider());
initialiseStandard(config);
initialiseJavaTimeTypes(config);
@@ -2,6 +2,7 @@ package io.ebeaninternal.server.type;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import io.ebean.config.TempFileProvider;
import io.ebean.core.type.DataBinder;
import io.ebean.core.type.DataReader;
import io.ebean.core.type.DocPropertyType;
@@ -17,26 +18,22 @@ import java.sql.Types;
*/
final class ScalarTypeFile extends ScalarTypeBase<File> {
private final String prefix;
private final String suffix;
private final File directory;
private final TempFileProvider tempFileProvider;
private final int bufferSize;
/**
* Construct with reasonable defaults of Blob and 8096 buffer size.
* Construct with reasonable defaults of Blob and 8192 buffer size.
*/
ScalarTypeFile() {
this(Types.LONGVARBINARY, "db-", null, null, 8096);
ScalarTypeFile(TempFileProvider tempFileProvider) {
this(Types.LONGVARBINARY, tempFileProvider, 8192);
}
/**
* Create the ScalarTypeFile.
*/
ScalarTypeFile(int jdbcType, String prefix, String suffix, File directory, int bufferSize) {
ScalarTypeFile(int jdbcType, TempFileProvider tempFileProvider, int bufferSize) {
super(File.class, false, jdbcType);
this.prefix = prefix;
this.suffix = suffix;
this.directory = directory;
this.tempFileProvider = tempFileProvider;
this.bufferSize = bufferSize;
}
@@ -63,7 +60,7 @@ final class ScalarTypeFile extends ScalarTypeBase<File> {
}
try {
// stream from db into our temp file
File tempFile = File.createTempFile(prefix, suffix, directory);
File tempFile = tempFileProvider.createTempFile();
OutputStream os = getOutputStream(tempFile);
pump(is, os);
return tempFile;
@@ -106,7 +103,7 @@ final class ScalarTypeFile extends ScalarTypeBase<File> {
@Override
public File jsonRead(JsonParser parser) throws IOException {
File tempFile = File.createTempFile(prefix, suffix, directory);
File tempFile = tempFileProvider.createTempFile();
try (OutputStream os = getOutputStream(tempFile)) {
parser.readBinaryValue(os);
os.flush();