-
Notifications
You must be signed in to change notification settings - Fork 31
STITCH-1950 Add collection level sync configuration #67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9e0d525
67934d8
6ef1770
7c5d841
17ae642
11721d0
2834054
0045d82
d899866
9def655
a752586
7c1f0ff
3320e7f
6842550
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,9 @@ | |
|
||
import java.util.Set; | ||
|
||
import javax.annotation.Nonnull; | ||
import javax.annotation.Nullable; | ||
|
||
import org.bson.BsonValue; | ||
import org.bson.conversions.Bson; | ||
|
||
|
@@ -33,15 +36,15 @@ | |
public interface CoreSync<DocumentT> { | ||
/** | ||
* Set the conflict resolver and and change event listener on this collection. | ||
* @param conflictResolver the conflict resolver to invoke when a conflict happens between local | ||
* and remote events. | ||
* @param conflictHandler the conflict resolver to invoke when a conflict happens between local | ||
* and remote events. | ||
* @param changeEventListener the event listener to invoke when a change event happens for the | ||
* document. | ||
* @param errorListener the error listener to invoke when an irrecoverable error occurs | ||
*/ | ||
void configure(final ConflictHandler<DocumentT> conflictResolver, | ||
final ChangeEventListener<DocumentT> changeEventListener, | ||
final ErrorListener errorListener); | ||
void configure(@Nonnull final ConflictHandler<DocumentT> conflictHandler, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nit] ditto |
||
@Nullable final ChangeEventListener<DocumentT> changeEventListener, | ||
@Nullable final ErrorListener errorListener); | ||
|
||
/** | ||
* Requests that the given document _id be synchronized. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,8 @@ | |
import com.mongodb.stitch.core.services.mongodb.remote.sync.ErrorListener; | ||
|
||
import java.util.Set; | ||
|
||
import javax.annotation.Nonnull; | ||
import javax.annotation.Nullable; | ||
|
||
import org.bson.BsonDocument; | ||
|
@@ -54,12 +56,12 @@ public CoreSyncImpl(final MongoNamespace namespace, | |
} | ||
|
||
@Override | ||
public void configure(final ConflictHandler<DocumentT> conflictResolver, | ||
final ChangeEventListener<DocumentT> changeEventListener, | ||
final ErrorListener errorListener) { | ||
public void configure(@Nonnull final ConflictHandler<DocumentT> conflictHandler, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nit] ditto |
||
@Nullable final ChangeEventListener<DocumentT> changeEventListener, | ||
@Nullable final ErrorListener errorListener) { | ||
this.dataSynchronizer.configure( | ||
namespace, | ||
conflictResolver, | ||
conflictHandler, | ||
changeEventListener, | ||
errorListener, | ||
this.service.getCodecRegistry().get(documentClass) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,6 +61,9 @@ | |
import java.util.concurrent.locks.Lock; | ||
import java.util.concurrent.locks.ReentrantLock; | ||
|
||
import javax.annotation.Nonnull; | ||
import javax.annotation.Nullable; | ||
|
||
import org.bson.BsonArray; | ||
import org.bson.BsonBoolean; | ||
import org.bson.BsonDocument; | ||
|
@@ -103,6 +106,8 @@ public class DataSynchronizer implements NetworkMonitor.StateListener { | |
|
||
private InstanceSynchronizationConfig syncConfig; | ||
private boolean syncThreadEnabled = true; | ||
private boolean isConfigured = false; | ||
private boolean isRunning = false; | ||
jsflax marked this conversation as resolved.
Show resolved
Hide resolved
|
||
private Thread syncThread; | ||
private long logicalT = 0; // The current logical time or sync iteration. | ||
|
||
|
@@ -195,24 +200,46 @@ public void reloadConfig() { | |
networkMonitor, | ||
authMonitor | ||
); | ||
this.isConfigured = false; | ||
this.stop(); | ||
} finally { | ||
syncLock.unlock(); | ||
} | ||
} | ||
|
||
public <T> void configure(@Nonnull final MongoNamespace namespace, | ||
@Nonnull final ConflictHandler<T> conflictHandler, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nit] ditto |
||
@Nullable final ChangeEventListener<T> changeEventListener, | ||
@Nullable final ErrorListener errorListener, | ||
@Nonnull final Codec<T> codec) { | ||
if (conflictHandler == null) { | ||
logger.warn( | ||
"Invalid configuration: conflictHandler should not be null. " | ||
+ "The DataSynchronizer will not begin syncing until a ConflictHandler has been " | ||
+ "provided."); | ||
return; | ||
} | ||
|
||
public <T> void configure(final MongoNamespace namespace, | ||
final ConflictHandler<T> conflictHandler, | ||
final ChangeEventListener<T> changeEventListener, | ||
final ErrorListener errorListener, | ||
final Codec<T> codec) { | ||
this.errorListener = errorListener; | ||
|
||
this.syncConfig.getNamespaceConfig(namespace).configure( | ||
conflictHandler, | ||
changeEventListener, | ||
codec | ||
); | ||
this.triggerListeningToNamespace(namespace); | ||
|
||
syncLock.lock(); | ||
if (!this.isConfigured) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [minor] We should grab the lock first before checking configured otherwise this can be a torn read or write. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
this.isConfigured = true; | ||
syncLock.unlock(); | ||
this.triggerListeningToNamespace(namespace); | ||
} else { | ||
syncLock.unlock(); | ||
} | ||
|
||
if (!isRunning) { | ||
jsflax marked this conversation as resolved.
Show resolved
Hide resolved
jsflax marked this conversation as resolved.
Show resolved
Hide resolved
|
||
this.start(); | ||
} | ||
} | ||
|
||
/** | ||
|
@@ -221,7 +248,7 @@ public <T> void configure(final MongoNamespace namespace, | |
public void start() { | ||
syncLock.lock(); | ||
try { | ||
if (syncThread != null) { | ||
if (syncThread != null || !this.isConfigured) { | ||
return; | ||
} | ||
instanceChangeStreamListener.start(); | ||
|
@@ -231,6 +258,7 @@ public void start() { | |
logger)); | ||
if (syncThreadEnabled) { | ||
syncThread.start(); | ||
isRunning = true; | ||
} | ||
} finally { | ||
syncLock.unlock(); | ||
|
@@ -263,6 +291,7 @@ public void stop() { | |
return; | ||
} | ||
syncThread = null; | ||
isRunning = false; | ||
} finally { | ||
syncLock.unlock(); | ||
} | ||
|
@@ -1025,6 +1054,7 @@ private void resolveConflict( | |
} else { | ||
// Update the document locally which will keep the pending writes but with | ||
// a new version next time around. | ||
@SuppressWarnings("unchecked") | ||
final BsonDocument docForStorage = | ||
BsonUtils.documentToBsonDocument( | ||
resolvedDocument, | ||
|
@@ -1467,7 +1497,7 @@ private void deleteOneFromRemote( | |
emitEvent(documentId, changeEventForLocalDelete(namespace, documentId, false)); | ||
} | ||
|
||
private void triggerListeningToNamespace(final MongoNamespace namespace) { | ||
void triggerListeningToNamespace(final MongoNamespace namespace) { | ||
syncLock.lock(); | ||
try { | ||
final NamespaceSynchronizationConfig nsConfig = this.syncConfig.getNamespaceConfig(namespace); | ||
|
@@ -1493,6 +1523,15 @@ private void triggerListeningToNamespace(final MongoNamespace namespace) { | |
} | ||
} | ||
|
||
/** | ||
* Whether or not the DataSynchronizer is running in the background. | ||
* | ||
* @return true if running, false if not | ||
*/ | ||
public boolean isRunning() { | ||
jsflax marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return isRunning; | ||
} | ||
|
||
public boolean areAllStreamsOpen() { | ||
syncLock.lock(); | ||
try { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] ditto