Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2009-08-03 16:47:26 +0000
committerEike Stepper2009-08-03 16:47:26 +0000
commit9f7ffe2b64a07ac04f19788eee55ccaf1789e307 (patch)
tree1e97a9d6de2455d2edfc3a51c892561b391daca6 /plugins
parent057a4cbc77d072ea776872fffeae189b850ef3ac (diff)
downloadcdo-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')
-rw-r--r--plugins/org.eclipse.emf.cdo.server.net4j/src/org/eclipse/emf/cdo/server/internal/net4j/protocol/CDOServerProtocol.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/SessionTest.java77
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/session/CDOSession.java25
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java66
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java4
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOSessionProtocol.java15
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOSession.java5
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);
/**

Back to the top