From d3fd17aab57defafff25e7b169cd7c92a9fcbf44 Mon Sep 17 00:00:00 2001 From: Winston Li Date: Sat, 17 Dec 2016 15:20:08 +0000 Subject: [PATCH] Improve javadocs around swapping/repos --- .../main/java/uk/ac/ic/wlgitbridge/Main.java | 5 ++- .../uk/ac/ic/wlgitbridge/bridge/Bridge.java | 30 ++++++++++---- .../wlgitbridge/bridge/lock/ProjectLock.java | 5 ++- .../ic/wlgitbridge/bridge/repo/RepoStore.java | 9 +++- .../wlgitbridge/bridge/swap/job/SwapJob.java | 41 +++++++++++++++++++ .../bridge/swap/job/SwapJobImpl.java | 23 +++++++++++ 6 files changed, 103 insertions(+), 10 deletions(-) diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/Main.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/Main.java index 13f6b1518f..4b3b9f422f 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/Main.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/Main.java @@ -32,7 +32,10 @@ public class Main { new GitBridgeApp(args).run(); } catch (Throwable t) { /* So that we get a timestamp */ - Log.error("Fatal exception thrown to top level, exiting: ", t); + Log.error( + "Fatal exception thrown to top level, exiting: ", + t + ); System.exit(1); } } diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/Bridge.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/Bridge.java index 158c1efd7b..eb4b1b96a5 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/Bridge.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/Bridge.java @@ -52,9 +52,6 @@ import java.sql.Timestamp; import java.time.LocalDateTime; import java.util.*; -/** - * Created by Winston on 16/11/14. - */ /** * This is the heart of the Git Bridge. You plug in all the parts (project * lock, repo store, db store, swap store, snapshot api, resource cache and @@ -272,7 +269,10 @@ public class Bridge { if (state != ProjectState.NOT_PRESENT) { continue; } - Log.warn("Project: {} not in swap_store, adding", projName); + Log.warn( + "Project: {} not in swap_store, adding", + projName + ); dbStore.setLastAccessedTime( projName, new Timestamp(dotGit.lastModified()) @@ -288,6 +288,13 @@ public class Bridge { * ourselves whether a project exists. If a user creates a project on the * app, and clones, the project is not on the git bridge disk and must ask * the snapshot API whether it exists. + * + * 1. Acquires the project lock. + * 2. Makes a docs request and tries to get the version ID. + * 3. If the version ID is valid, returns true. + * 4. Otherwise, the version ID is invalid, and throws + * InvalidProjectException, returning false. + * * @param oauth2 The oauth2 to use for the snapshot API * @param projectName The project name * @return true iff the project exists @@ -334,8 +341,14 @@ public class Bridge { } /** - * Synchronises the given repository with Overleaf. The project lock must - * be acquired. + * Synchronises the given repository with Overleaf. + * + * Pre: the project lock must be acquired for the given repo. + * + * 1. Queries the project state for the given project name. + * a. NOT_PRESENT = We've never seen it before, and the row for the + * project doesn't even exist. + * b. PRESENT = The * * If the project has never been cloned, it is git init'd. If the project * is in swap, it is restored to disk. Otherwise, the project was already @@ -407,7 +420,10 @@ public class Bridge { oldDirectoryContents ); } catch (SevereSnapshotPostException e) { - Log.warn("[" + projectName + "] Failed to put to Overleaf", e); + Log.warn( + "[" + projectName + "] Failed to put to Overleaf", + e + ); throw e; } catch (SnapshotPostException e) { /* Stack trace should be printed further up */ diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/lock/ProjectLock.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/lock/ProjectLock.java index 624004946f..98f6ae96c2 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/lock/ProjectLock.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/lock/ProjectLock.java @@ -1,7 +1,10 @@ package uk.ac.ic.wlgitbridge.bridge.lock; /** - * Created by winston on 20/08/2016. + * Project Lock class. + * + * The locks should be re-entrant. For example, we are usually holding the lock + * when a project must be restored, which tries to acquire the lock again. */ public interface ProjectLock { diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/repo/RepoStore.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/repo/RepoStore.java index bdb95ac828..c5b1f8b145 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/repo/RepoStore.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/repo/RepoStore.java @@ -39,11 +39,18 @@ public interface RepoStore { return bzip2Project(projectName, null); } + /** + * Called after {@link #bzip2Project(String, long[])}'s has been safely + * uploaded to the swap store. Removes all traces of the project from disk, + * i.e. not just its .git, but the whole project's git directory. + * @param projectName + * @throws IOException + */ void remove(String projectName) throws IOException; /** * Unbzip2s the given data stream into a .git directory for projectName. - * Creates the project directory. + * Creates the project's git directory. * If projectName already exists, throws an IOException. * @param projectName the name of the project, e.g. abc123 * @param dataStream the data stream containing the bzipped contents. diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/swap/job/SwapJob.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/swap/job/SwapJob.java index 54cfa703f2..05d6fbebb2 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/swap/job/SwapJob.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/swap/job/SwapJob.java @@ -32,12 +32,53 @@ public interface SwapJob { return new NoopSwapJob(); } + /** + * Starts the swap job, which should schedule an attempted swap at the given + * configured interval (config["swapJob"]["intervalMillis"] + */ void start(); + /** + * Stops the stop job. + */ void stop(); + /** + * Called by the swap job when a project should be evicted. + * + * Pre: + * 1. projName must be in repoStore + * 2. projName should not be in swapStore + * 3. projName should be PRESENT in dbStore (last_accessed is not null) + * + * Acquires the project lock and performs an eviction of projName. + * + * Post: + * 1. projName should not in repoStore + * 2. projName must be in swapStore + * 3. projName must be SWAPPED in dbStore (last_accessed is null) + * @param projName + * @throws IOException + */ void evict(String projName) throws IOException; + /** + * Called on a project when it must be restored. + * + * Pre: + * 1. projName should not be in repoStore + * 2. projName must be in swapStore + * 3. projName must be SWAPPED in dbStore (last_accessed is null) + * + * Acquires the project lock and restores projName. + * + * Post: + * 1. projName must be in repoStore + * 2. projName should not in swapStore + * 3. projName should be PRESENT in dbStore (last_accessed is not null) + * @param projName + * @throws IOException + */ void restore(String projName) throws IOException; } diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/swap/job/SwapJobImpl.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/swap/job/SwapJobImpl.java index fa919f7d5a..93c8bf3bf2 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/swap/job/SwapJobImpl.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/swap/job/SwapJobImpl.java @@ -143,6 +143,18 @@ public class SwapJobImpl implements SwapJob { swaps.incrementAndGet(); } + /** + * @see SwapJob#evict(String) for high-level description. + * + * 1. Acquires the project lock. + * 2. Gets a bz2 stream and size of a project from the repo store, or throws + * 3. Uploads the bz2 stream and size to the projName in the swapStore. + * 4. Sets the last accessed time in the dbStore to null, which makes our + * state SWAPPED + * 5. Removes the project from the repo store. + * @param projName + * @throws IOException + */ @Override public void evict(String projName) throws IOException { Preconditions.checkNotNull(projName); @@ -157,6 +169,17 @@ public class SwapJobImpl implements SwapJob { Log.info("Evicted project: {}", projName); } + /** + * @see SwapJob#restore(String) for high-level description. + * + * 1. Acquires the project lock. + * 2. Gets a bz2 stream for the project from the swapStore. + * 3. Fully downloads and places the bz2 stream back in the repo store. + * 4. Sets the last accessed time in the dbStore to now, which makes our + * state PRESENT and the last project to be evicted. + * @param projName + * @throws IOException + */ @Override public void restore(String projName) throws IOException { try (LockGuard __ = lock.lockGuard(projName)) {