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 @@ -4,6 +4,7 @@
import cn.hutool.core.util.ObjectUtil;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class ERPositionStorage extends SmallDataStorage<ERPosition> {
Expand Down Expand Up @@ -36,17 +37,49 @@ public String getPosition(Long dataSourceId, String databaseName, String schemaN
return null;
}

public void savePosition(ERPosition param) {
List<ERPosition> list = super.getDataList();
for (ERPosition p : list) {
if (p.getDataSourceId().equals(param.getDataSourceId()) &&
ObjectUtil.equals(p.getDatabaseName(), param.getDatabaseName())
&& ObjectUtil.equals(p.getSchemaName(), param.getSchemaName())) {
p.setPosition(param.getPosition());
update(p);
return;
public synchronized void savePosition(ERPosition param) {
if (param == null) {
return;
}
List<ERPosition> candidateList = new ArrayList<>(dataMap.size() + 1);
ERPosition replacement = null;
for (ERPosition current : dataMap.values()) {
ERPosition candidate = copy(current);
if (replacement == null && samePositionKey(current, param)) {
candidate.setPosition(param.getPosition());
replacement = candidate;
}
candidateList.add(candidate);
}
boolean inserted = replacement == null;
if (inserted) {
replacement = copy(param);
if (replacement.getId() == null) {
replacement.setId(generateId());
}
candidateList.add(replacement);
}

saveDataList(candidateList);
dataMap.put(replacement.getId(), replacement);
if (inserted) {
param.setId(replacement.getId());
}
super.save(param);
}

private boolean samePositionKey(ERPosition current, ERPosition update) {
return current.getDataSourceId().equals(update.getDataSourceId())
&& ObjectUtil.equals(current.getDatabaseName(), update.getDatabaseName())
&& ObjectUtil.equals(current.getSchemaName(), update.getSchemaName());
}

private ERPosition copy(ERPosition source) {
ERPosition copy = new ERPosition();
copy.setId(source.getId());
copy.setDataSourceId(source.getDataSourceId());
copy.setDatabaseName(source.getDatabaseName());
copy.setSchemaName(source.getSchemaName());
copy.setPosition(source.getPosition());
return copy;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,16 @@
import org.junit.jupiter.api.io.TempDir;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;

/**
* Regression test for {@link ERPositionStorage#savePosition}.
Expand Down Expand Up @@ -73,4 +80,43 @@ void getPositionReturnsNullForMissingKey() throws Exception {
ERPositionStorage storage = createStorage();
assertNull(storage.getPosition(99L, "missing", "missing"));
}

@Test
void failedPositionReplacementKeepsMemoryFileAndReloadState() throws Exception {
File storageFile = storageFile();
FailingERPositionStorage storage = new FailingERPositionStorage(storageFile);
storage.savePosition(pos(1L, "db1", "schema1", "old"));
ERPosition before = storage.getDataList().get(0);
String persisted = Files.readString(storageFile.toPath(), StandardCharsets.UTF_8);
storage.failWrites = true;

assertThrows(RuntimeException.class,
() -> storage.savePosition(pos(1L, "db1", "schema1", "new")));

ERPositionStorage reloaded = new ERPositionStorage(storageFile);
assertAll(
() -> assertSame(before, storage.getDataList().get(0)),
() -> assertEquals("old", storage.getPosition(1L, "db1", "schema1")),
() -> assertEquals(persisted,
Files.readString(storageFile.toPath(), StandardCharsets.UTF_8)),
() -> assertEquals("old", reloaded.getPosition(1L, "db1", "schema1"))
);
}

private static final class FailingERPositionStorage extends ERPositionStorage {

private boolean failWrites;

private FailingERPositionStorage(File storageFile) {
super(storageFile);
}

@Override
protected void replaceStorageFile(Path temp, Path target) throws IOException {
if (failWrites) {
throw new IOException("forced replace failure");
}
super.replaceStorageFile(temp, target);
}
}
}
Loading