Skip to content

Commit ec07efb

Browse files
committed
Simplify mongocryptd process-starting logic
* Attempt to start mongocryptd on MongoClient construction * Attempt to re-start mongocryptd on a MongoTimeoutException This fixes a bug where mongocryptd was not being restarted on MongoTimeoutException. JAVA-3071
1 parent b1ce857 commit ec07efb

File tree

2 files changed

+45
-58
lines changed

2 files changed

+45
-58
lines changed

driver-async/src/main/com/mongodb/async/client/internal/CommandMarker.java

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
class CommandMarker implements Closeable {
4040
private MongoClient client;
4141
private final ProcessBuilder processBuilder;
42-
private boolean active;
4342

4443
CommandMarker(final Map<String, Object> options) {
4544
String connectionString;
@@ -50,6 +49,13 @@ class CommandMarker implements Closeable {
5049
connectionString = "mongodb://localhost:27020";
5150
}
5251

52+
if (!options.containsKey("mongocryptdBypassSpawn") || !((Boolean) options.get("mongocryptdBypassSpawn"))) {
53+
processBuilder = new ProcessBuilder(createMongocryptdSpawnArgs(options));
54+
startProcess();
55+
} else {
56+
processBuilder = null;
57+
}
58+
5359
client = MongoClients.create(MongoClientSettings.builder()
5460
.applyConnectionString(new ConnectionString(connectionString))
5561
.applyToClusterSettings(new Block<ClusterSettings.Builder>() {
@@ -59,13 +65,6 @@ public void apply(final ClusterSettings.Builder builder) {
5965
}
6066
})
6167
.build());
62-
active = false;
63-
64-
if (!options.containsKey("mongocryptdBypassSpawn") || !((Boolean) options.get("mongocryptdBypassSpawn"))) {
65-
processBuilder = new ProcessBuilder(createMongocryptdSpawnArgs(options));
66-
} else {
67-
processBuilder = null;
68-
}
6968
}
7069

7170
void mark(final String databaseName, final RawBsonDocument command, final SingleResultCallback<RawBsonDocument> callback) {
@@ -79,13 +78,22 @@ public void onResult(final RawBsonDocument result, final Throwable t) {
7978
}
8079
}
8180
};
82-
executeCommand(databaseName, command, new SingleResultCallback<RawBsonDocument>() {
81+
runCommand(databaseName, command, new SingleResultCallback<RawBsonDocument>() {
8382
@Override
8483
public void onResult(final RawBsonDocument result, final Throwable t) {
8584
if (t == null) {
8685
wrappedCallback.onResult(result, null);
8786
} else if (t instanceof MongoTimeoutException && processBuilder != null) {
88-
executeCommand(databaseName, command, wrappedCallback);
87+
startProcessAndContinue(new SingleResultCallback<Void>() {
88+
@Override
89+
public void onResult(final Void result, final Throwable t) {
90+
if (t != null) {
91+
callback.onResult(null, t);
92+
} else {
93+
runCommand(databaseName, command, wrappedCallback);
94+
}
95+
}
96+
});
8997
} else {
9098
wrappedCallback.onResult(null, t);
9199
}
@@ -98,38 +106,28 @@ public void close() {
98106
client.close();
99107
}
100108

101-
private void executeCommand(final String databaseName, final RawBsonDocument markableCommand,
102-
final SingleResultCallback<RawBsonDocument> callback) {
103-
spawnIfNecessary(new SingleResultCallback<Void>(){
104-
@Override
105-
public void onResult(final Void result, final Throwable t) {
106-
if (t != null) {
107-
callback.onResult(null, t);
108-
} else {
109-
client.getDatabase(databaseName)
110-
.withReadConcern(ReadConcern.DEFAULT)
111-
.withReadPreference(ReadPreference.primary())
112-
.runCommand(markableCommand, RawBsonDocument.class, callback);
113-
}
114-
}
115-
});
109+
private void runCommand(final String databaseName, final RawBsonDocument command,
110+
final SingleResultCallback<RawBsonDocument> callback) {
111+
client.getDatabase(databaseName)
112+
.withReadConcern(ReadConcern.DEFAULT)
113+
.withReadPreference(ReadPreference.primary())
114+
.runCommand(command, RawBsonDocument.class, callback);
116115
}
117116

118-
private synchronized void spawnIfNecessary(final SingleResultCallback<Void> callback) {
117+
private void startProcessAndContinue(final SingleResultCallback<Void> callback) {
119118
try {
120-
if (processBuilder != null) {
121-
synchronized (this) {
122-
if (!active) {
123-
processBuilder.start();
124-
active = true;
125-
}
126-
}
127-
}
119+
startProcess();
128120
callback.onResult(null, null);
129121
} catch (Throwable t) {
130-
callback.onResult(null,
131-
new MongoClientException("Exception starting mongocryptd process. Is `mongocryptd` on the system path?", t));
122+
callback.onResult(null, t);
132123
}
133124
}
134125

126+
private void startProcess() {
127+
try {
128+
processBuilder.start();
129+
} catch (Throwable t) {
130+
throw new MongoClientException("Exception starting mongocryptd process. Is `mongocryptd` on the system path?", t);
131+
}
132+
}
135133
}

driver-sync/src/main/com/mongodb/client/internal/CommandMarker.java

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
class CommandMarker implements Closeable {
4141
private MongoClient client;
4242
private final ProcessBuilder processBuilder;
43-
private boolean active;
4443

4544
CommandMarker(final Map<String, Object> options) {
4645
String connectionString;
@@ -51,7 +50,14 @@ class CommandMarker implements Closeable {
5150
connectionString = "mongodb://localhost:27020";
5251
}
5352

54-
this.client = MongoClients.create(MongoClientSettings.builder()
53+
if (!options.containsKey("mongocryptdBypassSpawn") || !((Boolean) options.get("mongocryptdBypassSpawn"))) {
54+
processBuilder = new ProcessBuilder(createMongocryptdSpawnArgs(options));
55+
startProcess();
56+
} else {
57+
processBuilder = null;
58+
}
59+
60+
client = MongoClients.create(MongoClientSettings.builder()
5561
.applyConnectionString(new ConnectionString(connectionString))
5662
.applyToClusterSettings(new Block<ClusterSettings.Builder>() {
5763
@Override
@@ -60,26 +66,17 @@ public void apply(final ClusterSettings.Builder builder) {
6066
}
6167
})
6268
.build());
63-
this.active = false;
64-
65-
if (!options.containsKey("mongocryptdBypassSpawn") || !((Boolean) options.get("mongocryptdBypassSpawn"))) {
66-
processBuilder = new ProcessBuilder(createMongocryptdSpawnArgs(options));
67-
} else {
68-
processBuilder = null;
69-
}
7069
}
7170

7271
RawBsonDocument mark(final String databaseName, final RawBsonDocument command) {
73-
spawnIfNecesary();
74-
7572
try {
7673
try {
7774
return executeCommand(databaseName, command);
7875
} catch (MongoTimeoutException e) {
7976
if (processBuilder == null) { // mongocryptdBypassSpawn=true
8077
throw e;
8178
}
82-
spawnIfNecesary();
79+
startProcess();
8380
return executeCommand(databaseName, command);
8481
}
8582
} catch (MongoException e) {
@@ -99,16 +96,9 @@ private RawBsonDocument executeCommand(final String databaseName, final RawBsonD
9996
.runCommand(markableCommand, RawBsonDocument.class);
10097
}
10198

102-
private synchronized void spawnIfNecesary() {
99+
private void startProcess() {
103100
try {
104-
if (processBuilder != null) {
105-
synchronized (this) {
106-
if (!active) {
107-
processBuilder.start();
108-
active = true;
109-
}
110-
}
111-
}
101+
processBuilder.start();
112102
} catch (IOException e) {
113103
throw new MongoClientException("Exception starting mongocryptd process. Is `mongocryptd` on the system path?", e);
114104
}
@@ -117,5 +107,4 @@ private synchronized void spawnIfNecesary() {
117107
private MongoClientException wrapInClientException(final MongoException e) {
118108
return new MongoClientException("Exception in encryption library: " + e.getMessage(), e);
119109
}
120-
121110
}

0 commit comments

Comments
 (0)