diff --git a/services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/ProjectLock.java b/services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/ProjectLock.java new file mode 100644 index 0000000000..6c614c99d7 --- /dev/null +++ b/services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/ProjectLock.java @@ -0,0 +1,38 @@ +package uk.ac.ic.wlgitbridge.writelatex; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by Winston on 20/11/14. + */ +public class ProjectLock { + + private final Map projectLocks; + + public ProjectLock() { + projectLocks = new HashMap(); + } + + public void lockForProject(String projectName) { + System.out.println("Locking for: " + Thread.currentThread().getId()); + getLockForProjectName(projectName).lock(); + } + + public void unlockForProject(String projectName) { + System.out.println("Unlocking for: " + Thread.currentThread().getId()); + getLockForProjectName(projectName).unlock(); + } + + private synchronized Lock getLockForProjectName(String projectName) { + Lock lock = projectLocks.get(projectName); + if (lock == null) { + lock = new ReentrantLock(); + projectLocks.put(projectName, lock); + } + return lock; + } + +} diff --git a/services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/WriteLatexAPI.java b/services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/WriteLatexAPI.java index a2b7e9565b..524debfbaf 100644 --- a/services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/WriteLatexAPI.java +++ b/services/git-bridge/src/uk/ac/ic/wlgitbridge/writelatex/WriteLatexAPI.java @@ -20,7 +20,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; /** * Created by Winston on 16/11/14. @@ -30,34 +29,24 @@ public class WriteLatexAPI implements WriteLatexDataSource { private final WLDataModel dataModel; private final PostbackManager postbackManager; private final Map projectLocks; - private final Lock projectLocksLock; + private final ProjectLock mainProjectLock; public WriteLatexAPI(WLDataModel dataModel) { this.dataModel = dataModel; postbackManager = new PostbackManager(); projectLocks = new HashMap(); - projectLocksLock = new ReentrantLock(); - } - - private Lock getLockForProjectName(String projectName) { - projectLocksLock.lock(); - Lock lock = projectLocks.get(projectName); - if (lock == null) { - lock = new ReentrantLock(); - projectLocks.put(projectName, lock); - } - projectLocksLock.unlock(); - return lock; + mainProjectLock = new ProjectLock(); +// postbackLock = new ProjectLock(); } @Override public void lockForProject(String projectName) { - getLockForProjectName(projectName).lock(); + mainProjectLock.lockForProject(projectName); } @Override public void unlockForProject(String projectName) { - getLockForProjectName(projectName).unlock(); + mainProjectLock.unlockForProject(projectName); } @Override @@ -69,6 +58,8 @@ public class WriteLatexAPI implements WriteLatexDataSource { snapshotGetDocRequest.getResult().getVersionID(); } catch (InvalidProjectException e) { return false; + } catch (FailedConnectionException e) { + throw e; } finally { unlockForProject(projectName); } @@ -84,18 +75,26 @@ public class WriteLatexAPI implements WriteLatexDataSource { @Override public void putDirectoryContentsToProjectWithName(String projectName, RawDirectoryContents directoryContents, String hostname) throws SnapshotPostException, IOException, FailedConnectionException { - lockForProject(projectName); - System.out.println("Pushing project: " + projectName); - CandidateSnapshot candidate = dataModel.createCandidateSnapshotFromProjectWithContents(projectName, directoryContents, hostname); - SnapshotPushRequest snapshotPushRequest = new SnapshotPushRequest(candidate); - snapshotPushRequest.request(); - SnapshotPushRequestResult result = snapshotPushRequest.getResult(); - if (result.wasSuccessful()) { - candidate.approveWithVersionID(postbackManager.getVersionID(projectName)); - unlockForProject(projectName); - } else { - unlockForProject(projectName); - throw new OutOfDateException(); + mainProjectLock.lockForProject(projectName); + try { + System.out.println("Pushing project: " + projectName); + CandidateSnapshot candidate = dataModel.createCandidateSnapshotFromProjectWithContents(projectName, directoryContents, hostname); + SnapshotPushRequest snapshotPushRequest = new SnapshotPushRequest(candidate); + snapshotPushRequest.request(); + SnapshotPushRequestResult result = snapshotPushRequest.getResult(); + if (result.wasSuccessful()) { + candidate.approveWithVersionID(postbackManager.getVersionID(projectName)); + } else { + throw new OutOfDateException(); + } + } catch (SnapshotPostException e) { + throw e; + } catch (IOException e) { + throw e; + } catch (FailedConnectionException e) { + throw e; + } finally { + mainProjectLock.unlockForProject(projectName); } }