Browse Source

Fix per-key commit caching in DefaultGitSyncService

The lastCommit field was shared across all repository keys, causing
MissingObjectException when multiple repositories were registered.
When onUpdate fired for repo A it overwrote lastCommit, and subsequent
listFiles/getFileContent calls for repo B used repo A's commit whose
tree objects don't exist in repo B's object database.

Changed to a per-key Map<String, RevCommit> so each repository's
resolved commit is stored and retrieved independently.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
pull/15117/head
Viacheslav Klimov 3 months ago
parent
commit
a2ec1248fc
Failed to extract signature
  1. 16
      application/src/main/java/org/thingsboard/server/service/sync/DefaultGitSyncService.java

16
application/src/main/java/org/thingsboard/server/service/sync/DefaultGitSyncService.java

@ -48,7 +48,7 @@ public class DefaultGitSyncService implements GitSyncService {
private final Map<String, GitRepository> repositories = new ConcurrentHashMap<>();
private final Map<String, Runnable> updateListeners = new ConcurrentHashMap<>();
private RevCommit lastCommit;
private final Map<String, RevCommit> lastCommits = new ConcurrentHashMap<>();
@Override
public void registerSync(String key, String repoUri, String branch, long fetchFrequencyMs, Runnable onUpdate) {
@ -87,7 +87,7 @@ public class DefaultGitSyncService implements GitSyncService {
@Override
public List<RepoFile> listFiles(String key, String path, int depth, FileType type) {
GitRepository repository = getRepository(key);
return repository.listFilesAtCommit(lastCommit, path, depth).stream()
return repository.listFilesAtCommit(getLastCommit(key), path, depth).stream()
.filter(file -> type == null || file.type() == type)
.toList();
}
@ -96,7 +96,7 @@ public class DefaultGitSyncService implements GitSyncService {
@Override
public byte[] getFileContent(String key, String path) {
GitRepository repository = getRepository(key);
return repository.getFileContentAtCommit(path, lastCommit);
return repository.getFileContentAtCommit(path, getLastCommit(key));
}
@Override
@ -143,7 +143,7 @@ public class DefaultGitSyncService implements GitSyncService {
GitRepository repository = getRepository(key);
String branchRef = getBranchRef(repository);
try {
lastCommit = repository.resolveCommit(branchRef);
lastCommits.put(key, repository.resolveCommit(branchRef));
} catch (Throwable e) {
log.error("[{}] Failed to resolve commit for ref {}", key, branchRef, e);
return;
@ -166,6 +166,14 @@ public class DefaultGitSyncService implements GitSyncService {
return Path.of(repositoriesFolder, name);
}
private RevCommit getLastCommit(String key) {
RevCommit commit = lastCommits.get(key);
if (commit == null) {
throw new IllegalStateException(key + " repository has no resolved commit");
}
return commit;
}
private String getBranchRef(GitRepository repository) {
return "refs/remotes/origin/" + repository.getSettings().getDefaultBranch();
}

Loading…
Cancel
Save