Add SyncUtils#vertxWrap. This is something we wrap all mongo callbacks with so all business logic is ran on vertx worker threads. This is important for 2 reasons:

1. Running all of our logic on the vertx threads makes sense, as we're a vertx application. (This also allows us to utilize vertx's thread pool logic + config, instead of relying on mongo's thread pool)
2. The more important one, it allows exceptions to be processed (instead of swallowed by mongo) with relevant context information.

There is an overhead to the thread switching we'll be doing because of this, but doing all of our work on a better thought out thread pool and (more importantly) having stack traces completely make this change worth the overhead.
This commit is contained in:
Colin McDonald 2016-07-09 17:19:20 -04:00
parent 5de25c498b
commit d55325d255
14 changed files with 118 additions and 82 deletions

View File

@ -11,6 +11,7 @@ import lombok.AllArgsConstructor;
import lombok.Getter;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.actor.ActorType;
import net.frozenorb.apiv3.util.SyncUtils;
import org.bson.Document;
import java.time.Instant;
@ -32,15 +33,15 @@ public final class AccessToken {
@Getter private Instant lastUpdatedAt;
public static void findAll(SingleResultCallback<List<AccessToken>> callback) {
accessTokensCollection.find().into(new LinkedList<>(), callback);
accessTokensCollection.find().into(new LinkedList<>(), SyncUtils.vertxWrap(callback));
}
public static void findById(String id, SingleResultCallback<AccessToken> callback) {
accessTokensCollection.find(new Document("_id", id)).first(callback);
accessTokensCollection.find(new Document("_id", id)).first(SyncUtils.vertxWrap(callback));
}
public static void findByNameAndType(String actorName, ActorType actorType, SingleResultCallback<AccessToken> callback) {
accessTokensCollection.find(new Document("actorName", actorName).append("actorType", actorType.name())).first(callback);
accessTokensCollection.find(new Document("actorName", actorName).append("actorType", actorType.name())).first(SyncUtils.vertxWrap(callback));
}
private AccessToken() {} // For Jackson
@ -60,15 +61,15 @@ public final class AccessToken {
}
public void insert(SingleResultCallback<Void> callback) {
accessTokensCollection.insertOne(this, callback);
accessTokensCollection.insertOne(this, SyncUtils.vertxWrap(callback));
}
public void save(SingleResultCallback<UpdateResult> callback) {
accessTokensCollection.replaceOne(new Document("_id", id), this, callback);
accessTokensCollection.replaceOne(new Document("_id", id), this, SyncUtils.vertxWrap(callback));
}
public void delete(SingleResultCallback<DeleteResult> callback) {
accessTokensCollection.deleteOne(new Document("_id", id), callback);
accessTokensCollection.deleteOne(new Document("_id", id), SyncUtils.vertxWrap(callback));
}
}

View File

@ -10,6 +10,7 @@ import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.actor.Actor;
import net.frozenorb.apiv3.actor.ActorType;
import net.frozenorb.apiv3.auditLog.AuditLogActionType;
import net.frozenorb.apiv3.util.SyncUtils;
import org.bson.Document;
import org.bson.types.ObjectId;
@ -38,15 +39,15 @@ public final class AuditLogEntry {
@Getter private Map<String, Object> metadata;
public static void findPaginated(Document query, int skip, int pageSize, SingleResultCallback<List<AuditLogEntry>> callback) {
auditLogCollection.find(query).sort(new Document("performedAt", -1)).skip(skip).limit(pageSize).into(new LinkedList<>(), callback);
auditLogCollection.find(query).sort(new Document("performedAt", -1)).skip(skip).limit(pageSize).into(new LinkedList<>(), SyncUtils.vertxWrap(callback));
}
public static void findById(String id, SingleResultCallback<AuditLogEntry> callback) {
auditLogCollection.find(new Document("_id", id)).first(callback);
auditLogCollection.find(new Document("_id", id)).first(SyncUtils.vertxWrap(callback));
}
public static void find(Document query, SingleResultCallback<List<AuditLogEntry>> callback) {
auditLogCollection.find(query).into(new LinkedList<>(), callback);
auditLogCollection.find(query).into(new LinkedList<>(), SyncUtils.vertxWrap(callback));
}
private AuditLogEntry() {} // For Jackson
@ -65,7 +66,7 @@ public final class AuditLogEntry {
}
public void insert(SingleResultCallback<Void> callback) {
auditLogCollection.insertOne(this, callback);
auditLogCollection.insertOne(this, SyncUtils.vertxWrap(callback));
}
}

View File

@ -10,6 +10,7 @@ import fr.javatic.mongo.jacksonCodec.objectId.Id;
import lombok.Getter;
import lombok.Setter;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.util.SyncUtils;
import org.bson.Document;
import java.time.Instant;
@ -45,7 +46,7 @@ public final class BannedAsn {
}
public static void updateCache() {
bannedAsnsCollection.find().into(new LinkedList<>(), (bannedAsns, error) -> {
bannedAsnsCollection.find().into(new LinkedList<>(), SyncUtils.vertxWrap((bannedAsns, error) -> {
if (error != null) {
error.printStackTrace();
return;
@ -59,7 +60,7 @@ public final class BannedAsn {
bannedAsnIdCache = working;
bannedAsnCache = bannedAsns;
});
}));
}
private BannedAsn() {} // For Jackson
@ -79,17 +80,17 @@ public final class BannedAsn {
public void insert(SingleResultCallback<Void> callback) {
bannedAsnCache.add(this);
bannedAsnIdCache.put(id, this);
bannedAsnsCollection.insertOne(this, callback);
bannedAsnsCollection.insertOne(this, SyncUtils.vertxWrap(callback));
}
public void save(SingleResultCallback<UpdateResult> callback) {
bannedAsnsCollection.replaceOne(new Document("_id", id), this, callback);
bannedAsnsCollection.replaceOne(new Document("_id", id), this, SyncUtils.vertxWrap(callback));
}
public void delete(SingleResultCallback<DeleteResult> callback) {
bannedAsnCache.remove(this);
bannedAsnIdCache.remove(id);
bannedAsnsCollection.deleteOne(new Document("_id", id), callback);
bannedAsnsCollection.deleteOne(new Document("_id", id), SyncUtils.vertxWrap(callback));
}
}

View File

@ -11,6 +11,7 @@ import fr.javatic.mongo.jacksonCodec.objectId.Id;
import lombok.Getter;
import lombok.Setter;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.util.SyncUtils;
import org.bson.Document;
import java.time.Instant;
@ -46,7 +47,7 @@ public final class BannedCellCarrier {
}
public static void updateCache() {
bannedCellCarriersCollection.find().into(new LinkedList<>(), (bannedCellCarriers, error) -> {
bannedCellCarriersCollection.find().into(new LinkedList<>(), SyncUtils.vertxWrap((bannedCellCarriers, error) -> {
if (error != null) {
error.printStackTrace();
return;
@ -60,7 +61,7 @@ public final class BannedCellCarrier {
bannedCellCarrierIdCache = working;
bannedCellCarrierCache = bannedCellCarriers;
});
}));
}
private BannedCellCarrier() {} // For Jackson
@ -80,17 +81,17 @@ public final class BannedCellCarrier {
public void insert(SingleResultCallback<Void> callback) {
bannedCellCarrierCache.add(this);
bannedCellCarrierIdCache.put(id, this);
bannedCellCarriersCollection.insertOne(this, callback);
bannedCellCarriersCollection.insertOne(this, SyncUtils.vertxWrap(callback));
}
public void save(SingleResultCallback<UpdateResult> callback) {
bannedCellCarriersCollection.replaceOne(new Document("_id", id), this, callback);
bannedCellCarriersCollection.replaceOne(new Document("_id", id), this, SyncUtils.vertxWrap(callback));
}
public void delete(SingleResultCallback<DeleteResult> callback) {
bannedCellCarrierCache.remove(this);
bannedCellCarrierIdCache.remove(id);
bannedCellCarriersCollection.deleteOne(new Document("_id", id), callback);
bannedCellCarriersCollection.deleteOne(new Document("_id", id), SyncUtils.vertxWrap(callback));
}
}

View File

@ -10,6 +10,7 @@ import lombok.Getter;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.actor.Actor;
import net.frozenorb.apiv3.actor.ActorType;
import net.frozenorb.apiv3.util.SyncUtils;
import net.frozenorb.apiv3.util.TimeUtils;
import org.bson.Document;
import org.bson.types.ObjectId;
@ -38,19 +39,19 @@ public final class IpBan {
@Getter private String removalReason;
public static void findPaginated(Document query, int skip, int pageSize, SingleResultCallback<List<IpBan>> callback) {
ipBansCollection.find(query).sort(new Document("addedAt", -1)).skip(skip).limit(pageSize).into(new LinkedList<>(), callback);
ipBansCollection.find(query).sort(new Document("addedAt", -1)).skip(skip).limit(pageSize).into(new LinkedList<>(), SyncUtils.vertxWrap(callback));
}
public static void findById(String id, SingleResultCallback<IpBan> callback) {
ipBansCollection.find(new Document("_id", id)).first(callback);
ipBansCollection.find(new Document("_id", id)).first(SyncUtils.vertxWrap(callback));
}
public static void findByIp(String userIp, SingleResultCallback<List<IpBan>> callback) {
ipBansCollection.find(new Document("userIp", userIp)).into(new LinkedList<>(), callback);
ipBansCollection.find(new Document("userIp", userIp)).into(new LinkedList<>(), SyncUtils.vertxWrap(callback));
}
public static void findByIpGrouped(Iterable<String> userIps, SingleResultCallback<Map<String, List<IpBan>>> callback) {
ipBansCollection.find(new Document("userIp", new Document("$in", userIps))).into(new LinkedList<>(), (ipBans, error) -> {
ipBansCollection.find(new Document("userIp", new Document("$in", userIps))).into(new LinkedList<>(), SyncUtils.vertxWrap((ipBans, error) -> {
if (error != null) {
callback.onResult(null, error);
} else {
@ -66,7 +67,7 @@ public final class IpBan {
callback.onResult(result, null);
}
});
}));
}
private IpBan() {} // For Jackson
@ -145,7 +146,7 @@ public final class IpBan {
}
public void insert(SingleResultCallback<Void> callback) {
ipBansCollection.insertOne(this, callback);
ipBansCollection.insertOne(this, SyncUtils.vertxWrap(callback));
}
public void delete(User removedBy, String reason, SingleResultCallback<UpdateResult> callback) {
@ -153,7 +154,7 @@ public final class IpBan {
this.removedAt = Instant.now();
this.removalReason = reason;
ipBansCollection.replaceOne(new Document("_id", id), this, callback);
ipBansCollection.replaceOne(new Document("_id", id), this, SyncUtils.vertxWrap(callback));
}
}

View File

@ -11,6 +11,7 @@ import lombok.Getter;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.maxmind.MaxMindResult;
import net.frozenorb.apiv3.util.MaxMindUtils;
import net.frozenorb.apiv3.util.SyncUtils;
import org.bson.Document;
import java.time.Instant;
@ -28,11 +29,11 @@ public final class IpIntel {
@Getter private MaxMindResult result;
public static void findAll(SingleResultCallback<List<IpIntel>> callback) {
ipIntelCollection.find().sort(new Document("lastSeenAt", -1)).into(new LinkedList<>(), callback);
ipIntelCollection.find().sort(new Document("lastSeenAt", -1)).into(new LinkedList<>(), SyncUtils.vertxWrap(callback));
}
public static void findById(String id, SingleResultCallback<IpIntel> callback) {
ipIntelCollection.find(new Document("_id", id)).first(callback);
ipIntelCollection.find(new Document("_id", id)).first(SyncUtils.vertxWrap(callback));
}
public static void findOrCreateById(String id, SingleResultCallback<IpIntel> callback) {
@ -65,7 +66,7 @@ public final class IpIntel {
}
public static void findOrCreateByIdGrouped(Collection<String> search, SingleResultCallback<Map<String, IpIntel>> callback) {
ipIntelCollection.find(new Document("_id", new Document("$in", search))).into(new LinkedList<>(), (existingIntel, error) -> {
ipIntelCollection.find(new Document("_id", new Document("$in", search))).into(new LinkedList<>(), SyncUtils.vertxWrap((existingIntel, error) -> {
if (error != null) {
callback.onResult(null, error);
return;
@ -101,14 +102,14 @@ public final class IpIntel {
IpIntel newIpIntel = new IpIntel(ip, maxMindResult);
ipIntelCollection.insertOne(newIpIntel, (ignored, error3) -> {
ipIntelCollection.insertOne(newIpIntel, SyncUtils.vertxWrap((ignored, error3) -> {
if (error3 != null) {
createNewIntelFuture.fail(error3);
} else {
result.put(ip, newIpIntel);
createNewIntelFuture.complete();
}
});
}));
});
});
@ -119,7 +120,7 @@ public final class IpIntel {
callback.onResult(result, null);
}
});
});
}));
}
private IpIntel() {} // For Jackson

View File

@ -8,6 +8,7 @@ import fr.javatic.mongo.jacksonCodec.objectId.Id;
import lombok.Getter;
import lombok.Setter;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.util.SyncUtils;
import org.bson.Document;
import java.util.LinkedList;
@ -24,11 +25,11 @@ public final class NotificationTemplate {
@Getter @Setter private String body;
public static void findAll(SingleResultCallback<List<NotificationTemplate>> callback) {
notificationTemplatesCollection.find().into(new LinkedList<>(), callback);
notificationTemplatesCollection.find().into(new LinkedList<>(), SyncUtils.vertxWrap(callback));
}
public static void findById(String id, SingleResultCallback<NotificationTemplate> callback) {
notificationTemplatesCollection.find(new Document("_id", id)).first(callback);
notificationTemplatesCollection.find(new Document("_id", id)).first(SyncUtils.vertxWrap(callback));
}
private NotificationTemplate() {} // For Jackson
@ -59,11 +60,11 @@ public final class NotificationTemplate {
}
public void insert(SingleResultCallback<Void> callback) {
notificationTemplatesCollection.insertOne(this, callback);
notificationTemplatesCollection.insertOne(this, SyncUtils.vertxWrap(callback));
}
public void delete(SingleResultCallback<DeleteResult> callback) {
notificationTemplatesCollection.deleteOne(new Document("_id", id), callback);
notificationTemplatesCollection.deleteOne(new Document("_id", id), SyncUtils.vertxWrap(callback));
}
}

View File

@ -7,6 +7,7 @@ import fr.javatic.mongo.jacksonCodec.objectId.Id;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.util.SyncUtils;
import net.frozenorb.apiv3.util.ZangUtils;
import net.frozenorb.apiv3.zang.ZangResult;
import org.bson.Document;
@ -26,11 +27,11 @@ public final class PhoneIntel {
@Getter private ZangResult result;
public static void findAll(SingleResultCallback<List<PhoneIntel>> callback) {
phoneIntelCollection.find().sort(new Document("lastSeenAt", -1)).into(new LinkedList<>(), callback);
phoneIntelCollection.find().sort(new Document("lastSeenAt", -1)).into(new LinkedList<>(), SyncUtils.vertxWrap(callback));
}
public static void findById(String id, SingleResultCallback<PhoneIntel> callback) {
phoneIntelCollection.find(new Document("_id", id)).first(callback);
phoneIntelCollection.find(new Document("_id", id)).first(SyncUtils.vertxWrap(callback));
}
public static void findOrCreateById(String id, SingleResultCallback<PhoneIntel> callback) {
@ -46,13 +47,13 @@ public final class PhoneIntel {
} else {
PhoneIntel newPhoneIntel = new PhoneIntel(id, zangResult);
phoneIntelCollection.insertOne(newPhoneIntel, (ignored, error3) -> {
phoneIntelCollection.insertOne(newPhoneIntel, SyncUtils.vertxWrap((ignored, error3) -> {
if (error3 != null) {
callback.onResult(null, error3);
} else {
callback.onResult(newPhoneIntel, null);
}
});
}));
}
});
}

View File

@ -10,6 +10,7 @@ import lombok.Getter;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.actor.Actor;
import net.frozenorb.apiv3.actor.ActorType;
import net.frozenorb.apiv3.util.SyncUtils;
import net.frozenorb.apiv3.util.TimeUtils;
import org.bson.Document;
import org.bson.types.ObjectId;
@ -44,19 +45,19 @@ public final class Punishment {
public static void findByType(Collection<PunishmentType> types, SingleResultCallback<List<Punishment>> callback) {
Collection<String> convertedTypes = types.stream().map(PunishmentType::name).collect(Collectors.toList());
punishmentsCollection.find(new Document("type", new Document("$in", convertedTypes))).into(new LinkedList<>(), callback);
punishmentsCollection.find(new Document("type", new Document("$in", convertedTypes))).into(new LinkedList<>(), SyncUtils.vertxWrap(callback));
}
public static void findPaginated(Document query, int skip, int pageSize, SingleResultCallback<List<Punishment>> callback) {
punishmentsCollection.find(query).sort(new Document("addedAt", -1)).skip(skip).limit(pageSize).into(new LinkedList<>(), callback);
punishmentsCollection.find(query).sort(new Document("addedAt", -1)).skip(skip).limit(pageSize).into(new LinkedList<>(), SyncUtils.vertxWrap(callback));
}
public static void findById(String id, SingleResultCallback<Punishment> callback) {
punishmentsCollection.find(new Document("_id", id)).first(callback);
punishmentsCollection.find(new Document("_id", id)).first(SyncUtils.vertxWrap(callback));
}
public static void findByLinkedIpBanId(String id, SingleResultCallback<Punishment> callback) {
punishmentsCollection.find(new Document("linkedIpBanId", id)).first(callback);
punishmentsCollection.find(new Document("linkedIpBanId", id)).first(SyncUtils.vertxWrap(callback));
}
public static void findByUser(User user, SingleResultCallback<List<Punishment>> callback) {
@ -64,11 +65,11 @@ public final class Punishment {
}
public static void findByUser(UUID user, SingleResultCallback<List<Punishment>> callback) {
punishmentsCollection.find(new Document("user", user)).into(new LinkedList<>(), callback);
punishmentsCollection.find(new Document("user", user)).into(new LinkedList<>(), SyncUtils.vertxWrap(callback));
}
public static void findByUserGrouped(Iterable<UUID> users, SingleResultCallback<Map<UUID, List<Punishment>>> callback) {
punishmentsCollection.find(new Document("user", new Document("$in", users))).into(new LinkedList<>(), (punishments, error) -> {
punishmentsCollection.find(new Document("user", new Document("$in", users))).into(new LinkedList<>(), SyncUtils.vertxWrap((punishments, error) -> {
if (error != null) {
callback.onResult(null, error);
} else {
@ -84,7 +85,7 @@ public final class Punishment {
callback.onResult(result, null);
}
});
}));
}
public static void findByUserAndType(User user, Collection<PunishmentType> types, SingleResultCallback<List<Punishment>> callback) {
@ -93,7 +94,7 @@ public final class Punishment {
public static void findByUserAndType(UUID user, Collection<PunishmentType> types, SingleResultCallback<List<Punishment>> callback) {
Collection<String> convertedTypes = types.stream().map(PunishmentType::name).collect(Collectors.toList());
punishmentsCollection.find(new Document("user", user).append("type", new Document("$in", convertedTypes))).into(new LinkedList<>(), callback);
punishmentsCollection.find(new Document("user", user).append("type", new Document("$in", convertedTypes))).into(new LinkedList<>(), SyncUtils.vertxWrap(callback));
}
private Punishment() {} // For Jackson
@ -148,7 +149,7 @@ public final class Punishment {
}
public void insert(SingleResultCallback<Void> callback) {
punishmentsCollection.insertOne(this, callback);
punishmentsCollection.insertOne(this, SyncUtils.vertxWrap(callback));
}
public void delete(User removedBy, String reason, SingleResultCallback<UpdateResult> callback) {
@ -157,7 +158,7 @@ public final class Punishment {
this.removalReason = reason;
if (linkedIpBanId == null) {
punishmentsCollection.replaceOne(new Document("_id", id), this, callback);
punishmentsCollection.replaceOne(new Document("_id", id), this, SyncUtils.vertxWrap(callback));
return;
}
@ -172,11 +173,11 @@ public final class Punishment {
if (error2 != null) {
callback.onResult(null, error2);
} else {
punishmentsCollection.replaceOne(new Document("_id", id), this, callback);
punishmentsCollection.replaceOne(new Document("_id", id), this, SyncUtils.vertxWrap(callback));
}
});
} else {
punishmentsCollection.replaceOne(new Document("_id", id), this, callback);
punishmentsCollection.replaceOne(new Document("_id", id), this, SyncUtils.vertxWrap(callback));
}
});
}

View File

@ -8,6 +8,7 @@ import fr.javatic.mongo.jacksonCodec.Entity;
import fr.javatic.mongo.jacksonCodec.objectId.Id;
import lombok.Getter;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.util.SyncUtils;
import org.bson.Document;
import java.util.HashMap;
@ -46,7 +47,7 @@ public final class Rank {
}
public static void updateCache() {
ranksCollection.find().into(new LinkedList<>(), (ranks, error) -> {
ranksCollection.find().into(new LinkedList<>(), SyncUtils.vertxWrap((ranks, error) -> {
if (error != null) {
error.printStackTrace();
return;
@ -60,7 +61,7 @@ public final class Rank {
rankIdCache = working;
rankCache = ranks;
});
}));
}
private Rank() {} // For Jackson
@ -79,13 +80,13 @@ public final class Rank {
public void insert(SingleResultCallback<Void> callback) {
rankCache.add(this);
rankIdCache.put(id, this);
ranksCollection.insertOne(this, callback);
ranksCollection.insertOne(this, SyncUtils.vertxWrap(callback));
}
public void delete(SingleResultCallback<DeleteResult> callback) {
rankCache.remove(this);
rankIdCache.remove(id);
ranksCollection.deleteOne(new Document("_id", id), callback);
ranksCollection.deleteOne(new Document("_id", id), SyncUtils.vertxWrap(callback));
}
}

View File

@ -11,6 +11,7 @@ import fr.javatic.mongo.jacksonCodec.objectId.Id;
import lombok.Getter;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.serialization.gson.ExcludeFromReplies;
import net.frozenorb.apiv3.util.SyncUtils;
import org.bson.Document;
import java.time.Instant;
@ -47,7 +48,7 @@ public final class Server {
}
public static void updateCache() {
serversCollection.find().into(new LinkedList<>(), (servers, error) -> {
serversCollection.find().into(new LinkedList<>(), SyncUtils.vertxWrap((servers, error) -> {
if (error != null) {
error.printStackTrace();
return;
@ -61,7 +62,7 @@ public final class Server {
serverIdCache = working;
serverCache = servers;
});
}));
}
// TODO: This code isn't multi-instance safe AND will send more
@ -121,17 +122,17 @@ public final class Server {
public void insert(SingleResultCallback<Void> callback) {
serverCache.add(this);
serverIdCache.put(id, this);
serversCollection.insertOne(this, callback);
serversCollection.insertOne(this, SyncUtils.vertxWrap(callback));
}
public void save(SingleResultCallback<UpdateResult> callback) {
serversCollection.replaceOne(new Document("_id", id), this, callback);
serversCollection.replaceOne(new Document("_id", id), this, SyncUtils.vertxWrap(callback));
}
public void delete(SingleResultCallback<DeleteResult> callback) {
serverCache.remove(this);
serverIdCache.remove(id);
serversCollection.deleteOne(new Document("_id", id), callback);
serversCollection.deleteOne(new Document("_id", id), SyncUtils.vertxWrap(callback));
}
}

View File

@ -12,6 +12,7 @@ import lombok.Setter;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.serialization.gson.ExcludeFromReplies;
import net.frozenorb.apiv3.util.PermissionUtils;
import net.frozenorb.apiv3.util.SyncUtils;
import org.bson.Document;
import java.util.*;
@ -43,7 +44,7 @@ public final class ServerGroup {
}
public static void updateCache() {
serverGroupsCollection.find().into(new LinkedList<>(), (serverGroups, error) -> {
serverGroupsCollection.find().into(new LinkedList<>(), SyncUtils.vertxWrap((serverGroups, error) -> {
if (error != null) {
error.printStackTrace();
return;
@ -57,7 +58,7 @@ public final class ServerGroup {
serverGroupIdCache = working;
serverGroupCache = serverGroups;
});
}));
}
private ServerGroup() {} // For Jackson
@ -74,17 +75,17 @@ public final class ServerGroup {
public void insert(SingleResultCallback<Void> callback) {
serverGroupCache.add(this);
serverGroupIdCache.put(id, this);
serverGroupsCollection.insertOne(this, callback);
serverGroupsCollection.insertOne(this, SyncUtils.vertxWrap(callback));
}
public void save(SingleResultCallback<UpdateResult> callback) {
serverGroupsCollection.replaceOne(new Document("_id", id), this, callback);
serverGroupsCollection.replaceOne(new Document("_id", id), this, SyncUtils.vertxWrap(callback));
}
public void delete(SingleResultCallback<DeleteResult> callback) {
serverGroupCache.remove(this);
serverGroupIdCache.remove(id);
serverGroupsCollection.deleteOne(new Document("_id", id), callback);
serverGroupsCollection.deleteOne(new Document("_id", id), SyncUtils.vertxWrap(callback));
}
}

View File

@ -18,6 +18,7 @@ import io.vertx.core.Future;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.maxmind.MaxMindResult;
import net.frozenorb.apiv3.maxmind.MaxMindUserType;
@ -37,6 +38,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Slf4j
@Entity
@AllArgsConstructor
public final class User {
@ -75,30 +77,30 @@ public final class User {
public static void findById(UUID id, SingleResultCallback<User> callback) {
if (UuidUtils.isAcceptableUuid(id)) {
usersCollection.find(new Document("_id", id)).first(callback);
usersCollection.find(new Document("_id", id)).first(SyncUtils.vertxWrap(callback));
} else {
callback.onResult(null, null);
}
}
public static void findByPhone(String phoneNumber, SingleResultCallback<User> callback) {
usersCollection.find(new Document("phone", phoneNumber)).first(callback);
usersCollection.find(new Document("phone", phoneNumber)).first(SyncUtils.vertxWrap(callback));
}
public static void findByEmail(String email, SingleResultCallback<User> callback) {
usersCollection.find(new Document("email", email)).first(callback);
usersCollection.find(new Document("email", email)).first(SyncUtils.vertxWrap(callback));
}
public static void findByEmailToken(String emailToken, SingleResultCallback<User> callback) {
usersCollection.find(new Document("emailToken", emailToken)).first(callback);
usersCollection.find(new Document("emailToken", emailToken)).first(SyncUtils.vertxWrap(callback));
}
public static void findByLastUsername(String lastUsername, SingleResultCallback<User> callback) {
usersCollection.find(new Document("lastUsername", lastUsername)).first(callback);
usersCollection.find(new Document("lastUsername", lastUsername)).first(SyncUtils.vertxWrap(callback));
}
public static void findOrCreateByIdGrouped(Map<UUID, String> search, SingleResultCallback<Map<UUID, User>> callback) {
usersCollection.find(new Document("_id", new Document("$in", search.keySet()))).into(new LinkedList<>(), (users, error) -> {
usersCollection.find(new Document("_id", new Document("$in", search.keySet()))).into(new LinkedList<>(), SyncUtils.vertxWrap((users, error) -> {
if (error != null) {
callback.onResult(null, error);
return;
@ -146,7 +148,7 @@ public final class User {
callback.onResult(result, null);
}
});
});
}));
}
private User() {} // For Jackson
@ -551,7 +553,7 @@ public final class User {
}
private List<Rank> getRanksScoped(ServerGroup serverGroup, Iterable<Grant> grants) {
List<Rank> grantedRanks = new LinkedList<>();
Set<Rank> grantedRanks = new HashSet<>();
for (Grant grant : grants) {
if (!grant.isActive() || (serverGroup != null && !grant.appliesOn(serverGroup))) {
@ -563,11 +565,11 @@ public final class User {
}
if (grantedRanks.isEmpty()) {
grantedRanks.add(Rank.findById("default"));
return grantedRanks;
return ImmutableList.of(Rank.findById("default"));
}
Iterator<Rank> iterator = grantedRanks.iterator();
Set<Rank> copiedRanks = ImmutableSet.copyOf(grantedRanks);
// This is to remove redundant ranks. Say they have mod, mod-plus, admin, and youtuber,
// we should remove mod and mod-plus as it'll be made redundant by the higher ranked admin.
@ -575,7 +577,7 @@ public final class User {
Rank rank = iterator.next();
// Check all other ranks for inherited collision
for (Rank otherRank : grantedRanks) {
for (Rank otherRank : copiedRanks) {
if (otherRank == rank) {
continue;
}
@ -593,16 +595,17 @@ public final class User {
}
}
grantedRanks.sort((a, b) -> Ints.compare(b.getWeight(), a.getWeight()));
return grantedRanks;
List<Rank> grantedRanksList = new ArrayList<>(grantedRanks);
grantedRanksList.sort((a, b) -> Ints.compare(b.getWeight(), a.getWeight()));
return ImmutableList.copyOf(grantedRanksList);
}
public void insert(SingleResultCallback<Void> callback) {
usersCollection.insertOne(this, callback);
usersCollection.insertOne(this, SyncUtils.vertxWrap(callback));
}
public void save(SingleResultCallback<UpdateResult> callback) {
usersCollection.replaceOne(new Document("_id", id), this, callback);
usersCollection.replaceOne(new Document("_id", id), this, SyncUtils.vertxWrap(callback));
}
}

View File

@ -0,0 +1,21 @@
package net.frozenorb.apiv3.util;
import com.mongodb.async.SingleResultCallback;
import io.vertx.core.Context;
import lombok.experimental.UtilityClass;
import net.frozenorb.apiv3.APIv3;
@UtilityClass
public class SyncUtils {
public static <T> SingleResultCallback<T> vertxWrap(SingleResultCallback<T> callback) {
Context context = APIv3.getVertxInstance().getOrCreateContext();
return (result, error) -> {
context.runOnContext((ignored) -> {
callback.onResult(result, error);
});
};
}
}