diff options
author | Eike Stepper | 2009-08-03 16:47:26 +0000 |
---|---|---|
committer | Eike Stepper | 2009-08-03 16:47:26 +0000 |
commit | 9f7ffe2b64a07ac04f19788eee55ccaf1789e307 (patch) | |
tree | 1e97a9d6de2455d2edfc3a51c892561b391daca6 /plugins | |
parent | 057a4cbc77d072ea776872fffeae189b850ef3ac (diff) | |
download | cdo-9f7ffe2b64a07ac04f19788eee55ccaf1789e307.tar.gz cdo-9f7ffe2b64a07ac04f19788eee55ccaf1789e307.tar.xz cdo-9f7ffe2b64a07ac04f19788eee55ccaf1789e307.zip |
[283947] Wait for commit operation of transaction A is visible in transaction B
https://bugs.eclipse.org/bugs/show_bug.cgi?id=283947
Diffstat (limited to 'plugins')
7 files changed, 188 insertions, 6 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java index c43fbd0b0b..9aafeff905 100644 --- a/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java +++ b/plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java @@ -90,7 +90,7 @@ public class CDOServerProtocol extends SignalProtocol<InternalSession> implement { try { - if (!dirtyIDs.isEmpty() || !newDeltas.isEmpty() || !detachedObjects.isEmpty() || packageUnits.length > 0) + // if (!dirtyIDs.isEmpty() || !newDeltas.isEmpty() || !detachedObjects.isEmpty() || packageUnits.length > 0) { IChannel channel = getChannel(); if (LifecycleUtil.isActive(channel)) diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/SessionTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/SessionTest.java index 70e1239143..6bd9a22d5f 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/SessionTest.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/SessionTest.java @@ -14,8 +14,10 @@ import org.eclipse.emf.cdo.server.IRepository; import org.eclipse.emf.cdo.session.CDOSession; import org.eclipse.emf.cdo.tests.config.impl.RepositoryConfig; import org.eclipse.emf.cdo.tests.config.impl.SessionConfig; +import org.eclipse.emf.cdo.transaction.CDOTransaction; import org.eclipse.net4j.signal.RemoteException; +import org.eclipse.net4j.util.concurrent.ConcurrencyUtil; import org.eclipse.net4j.util.security.PasswordCredentials; import org.eclipse.net4j.util.security.PasswordCredentialsProvider; import org.eclipse.net4j.util.security.UserManager; @@ -38,6 +40,81 @@ public class SessionTest extends AbstractCDOTest session.close(); } + public void testLastUpdateLocal() throws Exception + { + CDOSession session = openSession(); + CDOTransaction transaction = session.openTransaction(); + transaction.createResource("ttt"); + transaction.commit(); + + waitForUpdate(transaction.getLastCommitTime(), session); + session.close(); + } + + public void testLastUpdateRemote() throws Exception + { + CDOSession session1 = openSession(); + final CDOTransaction transaction = session1.openTransaction(); + transaction.createResource("ttt"); + transaction.commit(); + + final CDOSession session2 = openSession(); + waitForUpdate(transaction.getLastCommitTime(), session2); + + transaction.createResource("xxx"); + transaction.commit(); + waitForUpdate(transaction.getLastCommitTime(), session2); + + session1.close(); + session2.close(); + } + + private void waitForUpdate(final long updateTime, final CDOSession session) throws InterruptedException + { + new PollingTimeOuter() + { + @Override + protected boolean successful() + { + return updateTime == session.getLastUpdateTime(); + } + }.assertNoTimeOut(); + } + + public void testWaitForUpdateLocal() throws Exception + { + CDOSession session = openSession(); + CDOTransaction transaction = session.openTransaction(); + transaction.createResource("ttt"); + transaction.commit(); + + assertEquals(true, session.waitForUpdate(transaction.getLastCommitTime(), DEFAULT_TIMEOUT)); + session.close(); + } + + public void testWaitForUpdateRemote() throws Exception + { + final CDOTransaction transaction = openSession().openTransaction(); + transaction.createResource("ttt"); + + new Thread() + { + @Override + public void run() + { + ConcurrencyUtil.sleep(4000); + msg("Committing NOW!"); + transaction.commit(); + }; + }.start(); + + CDOSession session2 = openSession(); + assertEquals(true, session2.waitForUpdate(System.currentTimeMillis() + 2000L, DEFAULT_TIMEOUT)); + + transaction.getSession().close(); + session2.close(); + } + public void testNoAuthentication() throws Exception { IRepository repository = getRepository("authrepo"); diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSession.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSession.java index 1b2d48d630..16dbd0e908 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSession.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSession.java @@ -161,6 +161,31 @@ public interface CDOSession extends CDOCommonSession, IContainer<CDOView>, IOpti public Collection<CDOTimeStampContext> refresh(); /** + * Returns the time stamp of the last commit operation. May not be accurate if + * {@link Options#isPassiveUpdateEnabled() passive updates} are disabled. + * + * @since 3.0 + */ + public long getLastUpdateTime(); + + /** + * Blocks the calling thread until a commit operation with the given time stamp or higher has occured. + * + * @since 3.0 + */ + public void waitForUpdate(long updateTime); + + /** + * Blocks the calling thread until a commit operation with the given time stamp or higher has occured or the given + * timeout has expired. + * + * @return <code>true</code> if the specified commit operation has occured within the given timeout period, + * <code>false</code> otherwise. + * @since 3.0 + */ + public boolean waitForUpdate(long updateTime, long timeoutMillis); + + /** * Returns the {@link Options options} of this session. */ public Options options(); diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java index e61cb1f032..5164f551d8 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java @@ -99,6 +99,8 @@ public abstract class CDOSessionImpl extends Container<CDOView> implements Inter { private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_SESSION, CDOSessionImpl.class); + private static final long NO_TIMEOUT = -1; + private InternalCDOSessionConfiguration configuration; private ExceptionHandler exceptionHandler; @@ -119,6 +121,11 @@ public abstract class CDOSessionImpl extends Container<CDOView> implements Inter private String userID; + private long lastUpdateTime; + + @ExcludeFromDump + private Object lastUpdateTimeLock = new Object(); + private CDOSession.Options options = createOptions(); private CDORepositoryInfo repositoryInfo; @@ -137,13 +144,13 @@ public abstract class CDOSessionImpl extends Container<CDOView> implements Inter private Set<InternalCDOView> views = new HashSet<InternalCDOView>(); @ExcludeFromDump - private transient QueueRunner invalidationRunner; + private QueueRunner invalidationRunner; @ExcludeFromDump - private transient Object invalidationRunnerLock = new Object(); + private Object invalidationRunnerLock = new Object(); @ExcludeFromDump - private transient int lastViewID; + private int lastViewID; public CDOSessionImpl(InternalCDOSessionConfiguration configuration) { @@ -480,6 +487,58 @@ public abstract class CDOSessionImpl extends Container<CDOView> implements Inter return Collections.emptyList(); } + public long getLastUpdateTime() + { + synchronized (lastUpdateTimeLock) + { + return lastUpdateTime; + } + } + + public void setLastUpdateTime(long lastUpdateTime) + { + synchronized (lastUpdateTimeLock) + { + this.lastUpdateTime = lastUpdateTime; + lastUpdateTimeLock.notifyAll(); + } + } + + public void waitForUpdate(long updateTime) + { + waitForUpdate(updateTime, NO_TIMEOUT); + } + + public boolean waitForUpdate(long updateTime, long timeoutMillis) + { + long end = timeoutMillis == NO_TIMEOUT ? Long.MAX_VALUE : System.currentTimeMillis() + timeoutMillis; + for (;;) + { + synchronized (lastUpdateTimeLock) + { + if (lastUpdateTime >= updateTime) + { + return true; + } + + long now = System.currentTimeMillis(); + if (now >= end) + { + return false; + } + + try + { + lastUpdateTimeLock.wait(end - now); + } + catch (InterruptedException ex) + { + throw WrappedException.wrap(ex); + } + } + } + } + /** * @since 3.0 */ @@ -600,6 +659,7 @@ public abstract class CDOSessionImpl extends Container<CDOView> implements Inter } } + setLastUpdateTime(timeStamp); fireInvalidationEvent(timeStamp, newPackageUnits, dirtyOIDs, detachedObjects, excludedView); } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java index b27eb24f2a..a4e3515ee4 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java @@ -1399,6 +1399,10 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa session.handleCommitNotification(timeStamp, newPackageUnits, dirtyIDs, detachedIDs, deltasCopy, getTransaction()); } + else + { + session.setLastUpdateTime(timeStamp); + } lastCommitTime = timeStamp; for (CDOTransactionHandler handler : getHandlers()) diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java index 6772d2eafd..f9d0a9c690 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java @@ -139,6 +139,8 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, Revision private long repositoryCreationTime; + private long lastUpdateTime; + private RepositoryTimeResult repositoryTimeResult; private boolean repositorySupportingAudits; @@ -148,12 +150,13 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, Revision /** * @since 3.0 */ - public OpenSessionResult(int sessionID, String repositoryUUID, long repositoryCreationTime, + public OpenSessionResult(int sessionID, String repositoryUUID, long repositoryCreationTime, long lastUpdateTime, boolean repositorySupportingAudits) { this.sessionID = sessionID; this.repositoryUUID = repositoryUUID; this.repositoryCreationTime = repositoryCreationTime; + this.lastUpdateTime = lastUpdateTime; this.repositorySupportingAudits = repositorySupportingAudits; } @@ -187,6 +190,14 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, Revision this.repositoryTimeResult = repositoryTimeResult; } + /** + * @since 3.0 + */ + public long getLastUpdateTime() + { + return lastUpdateTime; + } + public List<InternalCDOPackageUnit> getPackageUnits() { return packageUnits; @@ -268,7 +279,7 @@ public interface CDOSessionProtocol extends CDOProtocol, PackageLoader, Revision { return MessageFormat .format( - "RepositoryTime[requested={0,date} {0,time}, indicated={1,date} {1,time}, responded={2,date} {2,time}, confirmed={3,date} {3,time}]", //$NON-NLS-1$ + "RepositoryTime[requested={0,date} {0,time}, indicated={1,date} {1,time}, responded={2,date} {2,time}, confirmed={3,date} {3,time}]", requested, indicated, responded, confirmed); } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java index 3c92432a64..d07a7b782c 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java @@ -85,6 +85,11 @@ public interface InternalCDOSession extends CDOSession, PackageProcessor, Packag public void setUserID(String userID); + /** + * @since 3.0 + */ + public void setLastUpdateTime(long lastUpdateTime); + public void viewDetached(InternalCDOView view); /** |