mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Speculative solution
This commit is contained in:
parent
19075f18bc
commit
4f3021cca1
6 changed files with 90 additions and 7 deletions
|
@ -9,6 +9,7 @@
|
|||
<version>1.0-SNAPSHOT</version>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.test.skip>true</maven.test.skip>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
|
|
|
@ -37,6 +37,7 @@ import uk.ac.ic.wlgitbridge.server.PostbackContents;
|
|||
import uk.ac.ic.wlgitbridge.server.PostbackHandler;
|
||||
import uk.ac.ic.wlgitbridge.snapshot.base.MissingRepositoryException;
|
||||
import uk.ac.ic.wlgitbridge.snapshot.base.ForbiddenException;
|
||||
import uk.ac.ic.wlgitbridge.snapshot.getdoc.GetDocResult;
|
||||
import uk.ac.ic.wlgitbridge.snapshot.getforversion.SnapshotAttachment;
|
||||
import uk.ac.ic.wlgitbridge.snapshot.push.PostbackManager;
|
||||
import uk.ac.ic.wlgitbridge.snapshot.push.PostbackPromise;
|
||||
|
@ -299,7 +300,7 @@ public class Bridge {
|
|||
* Synchronises the given repository with Overleaf.
|
||||
*
|
||||
* It acquires the project lock and calls
|
||||
* {@link #getUpdatedRepoCritical(Optional, String)}.
|
||||
* {@link #getUpdatedRepoCritical(Optional, String, GetDocResult)}.
|
||||
* @param oauth2 The oauth2 to use
|
||||
* @param projectName The name of the project
|
||||
* @throws IOException
|
||||
|
@ -310,11 +311,13 @@ public class Bridge {
|
|||
String projectName
|
||||
) throws IOException, GitUserException {
|
||||
try (LockGuard __ = lock.lockGuard(projectName)) {
|
||||
if (!snapshotAPI.projectExists(oauth2, projectName)) {
|
||||
Optional<GetDocResult> maybeDoc = snapshotAPI.getDoc(oauth2, projectName);
|
||||
if (!maybeDoc.isPresent()) {
|
||||
throw new RepositoryNotFoundException(projectName);
|
||||
}
|
||||
GetDocResult doc = maybeDoc.get();
|
||||
Log.info("[{}] Updating repository", projectName);
|
||||
return getUpdatedRepoCritical(oauth2, projectName);
|
||||
return getUpdatedRepoCritical(oauth2, projectName, doc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -346,14 +349,49 @@ public class Bridge {
|
|||
*/
|
||||
private ProjectRepo getUpdatedRepoCritical(
|
||||
Optional<Credential> oauth2,
|
||||
String projectName
|
||||
String projectName,
|
||||
GetDocResult doc
|
||||
) throws IOException, GitUserException {
|
||||
ProjectRepo repo;
|
||||
ProjectState state = dbStore.getProjectState(projectName);
|
||||
Log.info(">>>> RepoStore {}", repoStore.getRepoStorePath());
|
||||
Log.info(
|
||||
">>>> getUpdatedRepoCritical, {} migratedFrom {}",
|
||||
projectName,
|
||||
doc.getMigratedFromID()
|
||||
);
|
||||
switch (state) {
|
||||
case NOT_PRESENT:
|
||||
repo = repoStore.initRepo(projectName);
|
||||
break;
|
||||
Log.info(">>>> Not present {}", projectName);
|
||||
String migratedFromID = doc.getMigratedFromID();
|
||||
if (migratedFromID != null) {
|
||||
Log.info(">>>> has a migratedFromId {} {}", projectName, migratedFromID);
|
||||
ProjectState sourceState = dbStore.getProjectState(migratedFromID);
|
||||
try (LockGuard __ = lock.lockGuard(migratedFromID)) {
|
||||
switch (sourceState) {
|
||||
case NOT_PRESENT:
|
||||
// Normal init-repo
|
||||
Log.info(">>>> migrated-from-id not present, proceed as normal");
|
||||
repo = repoStore.initRepo(projectName);
|
||||
break;
|
||||
case SWAPPED:
|
||||
// Swap back and then copy
|
||||
Log.info(">>>> migrated-from-id swapped, unswap and proceed");
|
||||
swapJob.restore(migratedFromID);
|
||||
/* Fallthrough */
|
||||
default:
|
||||
// Copy data, and set version to zero
|
||||
Log.info(">>>> migrated-from-id init from existing");
|
||||
repo = repoStore.initRepoFromExisting(projectName, migratedFromID);
|
||||
dbStore.setLatestVersionForProject(migratedFromID, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
Log.info(">>>> no migrated-from-id {}", projectName);
|
||||
repo = repoStore.initRepo(projectName);
|
||||
break;
|
||||
}
|
||||
case SWAPPED:
|
||||
swapJob.restore(projectName);
|
||||
/* Fallthrough */
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.google.api.client.repackaged.com.google.common.base.Preconditions;
|
|||
import org.apache.commons.io.FileUtils;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import uk.ac.ic.wlgitbridge.util.Log;
|
||||
import uk.ac.ic.wlgitbridge.util.Project;
|
||||
import uk.ac.ic.wlgitbridge.util.Tar;
|
||||
|
||||
|
@ -74,6 +75,38 @@ public class FSGitRepoStore implements RepoStore {
|
|||
ret, Optional.of(maxFileSize), Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectRepo initRepoFromExisting(
|
||||
String project, String fromProject
|
||||
) throws IOException {
|
||||
GitProjectRepo ret = GitProjectRepo.fromName(project);
|
||||
// GitProjectRepo origin = GitProjectRepo.fromName(fromProject);
|
||||
ret.initRepo(this);
|
||||
Log.info(">>>> Copy from {} to {}", fromProject, project);
|
||||
String repoRoot = getRepoStorePath();
|
||||
String sourcePath = repoRoot + "/" + fromProject;
|
||||
String destinationPath = repoRoot + "/" + project;
|
||||
Log.info(">>>> paths from: {} and to: {}", sourcePath, destinationPath);
|
||||
new ProcessBuilder(
|
||||
"rm", "-rf",
|
||||
destinationPath
|
||||
).start();
|
||||
Process copyProcess = new ProcessBuilder(
|
||||
"cp", "-ra",
|
||||
sourcePath,
|
||||
destinationPath + "/"
|
||||
).start();
|
||||
Log.info(">>>> done copy");
|
||||
try {
|
||||
copyProcess.waitFor();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
throw new IOException("copy failed" + e.getLocalizedMessage());
|
||||
}
|
||||
return new WalkOverrideGitRepo(
|
||||
ret, Optional.of(maxFileSize), Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectRepo getExistingRepo(String project) throws IOException {
|
||||
GitProjectRepo ret = GitProjectRepo.fromName(project);
|
||||
|
|
|
@ -22,6 +22,8 @@ public interface RepoStore {
|
|||
|
||||
ProjectRepo initRepo(String project) throws IOException;
|
||||
|
||||
ProjectRepo initRepoFromExisting(String project, String fromProject) throws IOException;
|
||||
|
||||
ProjectRepo getExistingRepo(String project) throws IOException;
|
||||
|
||||
ProjectRepo useJGitRepo(Repository repo, ObjectId commitId);
|
||||
|
|
|
@ -44,6 +44,15 @@ public class SnapshotApiFacade {
|
|||
}
|
||||
}
|
||||
|
||||
public Optional<GetDocResult> getDoc(
|
||||
Optional<Credential> oauth2,
|
||||
String projectName
|
||||
) throws FailedConnectionException, GitUserException {
|
||||
GetDocResult doc = SnapshotApi
|
||||
.getResult(api.getDoc(oauth2, projectName));
|
||||
return Optional.ofNullable(doc);
|
||||
}
|
||||
|
||||
public Deque<Snapshot> getSnapshots(
|
||||
Optional<Credential> oauth2,
|
||||
String projectName,
|
||||
|
|
|
@ -90,7 +90,7 @@ public class WLRepositoryResolver
|
|||
return bridge.getUpdatedRepo(oauth2, projName).getJGitRepository();
|
||||
} catch (RepositoryNotFoundException e) {
|
||||
Log.info("Repository not found: " + name);
|
||||
throw e;
|
||||
throw new RepositoryNotFoundException("derp");
|
||||
/*
|
||||
} catch (ServiceNotAuthorizedException e) {
|
||||
cannot occur
|
||||
|
|
Loading…
Reference in a new issue