Skip to content

Commit 347ad6f

Browse files
authored
fix: service register could race and lead to multiple register calls (#1848)
### Motivation The service cache of the bridge was not being updated in a thread safe manner. This lead to multiple registration handler calls which at the end results in multiple registrations on velocity / bungeecord. ### Modification Made sure that the register and unregister calls do not race against other incoming updates. ### Result No races between service registration updates ##### Other context This issue from discord is probably an example for the described race https://discord.com/channels/325362837184577536/818777626663321671/1467177343729664316
1 parent 15cc106 commit 347ad6f

1 file changed

Lines changed: 10 additions & 13 deletions

File tree

modules/bridge/impl/src/main/java/eu/cloudnetservice/modules/bridge/impl/platform/PlatformBridgeManagement.java

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -194,21 +194,18 @@ public void handleTaskUpdate(@NonNull String name, @Nullable ServiceTask task) {
194194
}
195195

196196
public void handleServiceUpdate(@NonNull ServiceInfoSnapshot snapshot) {
197-
// if the service is not yet cached check if we need to cache it
198-
if (!this.cachedServices.containsKey(snapshot.serviceId().uniqueId())) {
199-
// check if we should cache it
200-
if (this.cacheTester.test(snapshot)) {
197+
var serviceUniqueId = snapshot.serviceId().uniqueId();
198+
if (this.cacheTester.test(snapshot)) {
199+
var previous = this.cachedServices.put(serviceUniqueId, snapshot);
200+
if (previous == null) {
201201
this.cacheRegisterListener.accept(snapshot);
202-
this.cachedServices.put(snapshot.serviceId().uniqueId(), snapshot);
203-
}
204-
} else {
205-
// if the service is already cached we need to check if we should still cache it
206-
if (this.cacheTester.test(snapshot)) {
207-
this.cachedServices.replace(snapshot.serviceId().uniqueId(), snapshot);
208-
} else {
209-
this.cacheUnregisterListener.accept(snapshot);
210-
this.cachedServices.remove(snapshot.serviceId().uniqueId());
211202
}
203+
return;
204+
}
205+
206+
var cachedService = this.cachedServices.remove(serviceUniqueId);
207+
if (cachedService != null) {
208+
this.cacheUnregisterListener.accept(snapshot);
212209
}
213210
}
214211

0 commit comments

Comments
 (0)