use of net.robinfriedli.exec.Mode in project aiode by robinfriedli.
the class Artist method getOrCreateArtist.
/**
* Get the existing artist with the provided or create a new artist. This method runs synchronised on the artist id
* to avoid unique constraint violations during concurrent creation.
*
* @param artist the spotify artist
* @param session the hibernate session
*/
public static Artist getOrCreateArtist(ArtistSimplified artist, Session session) {
QueryBuilderFactory queryBuilderFactory = Aiode.get().getQueryBuilderFactory();
Mode mode = Mode.create().with(new MutexSyncMode<>(artist.getId(), ARTIST_SYNC));
return HibernateInvoker.create(session).invokeFunction(mode, currentSession -> {
Optional<Artist> existingArtist = queryBuilderFactory.find(Artist.class).where((cb, root) -> cb.equal(root.get("id"), artist.getId())).build(currentSession).uniqueResultOptional();
return existingArtist.orElseGet(() -> {
Artist newArtist = new Artist(artist.getId(), artist.getName());
currentSession.persist(newArtist);
currentSession.flush();
return newArtist;
});
});
}
use of net.robinfriedli.exec.Mode in project aiode by robinfriedli.
the class AbstractCommand method invoke.
protected <E> E invoke(Callable<E> callable) {
HibernateInvoker hibernateInvoker = HibernateInvoker.create(context.getSession());
Mode mode = Mode.create().with(new MutexSyncMode<>(context.getGuild().getIdLong(), GUILD_MUTEX_SYNC));
return hibernateInvoker.invoke(mode, callable);
}
use of net.robinfriedli.exec.Mode in project aiode by robinfriedli.
the class AbstractCommand method invokeWithSession.
protected <E> E invokeWithSession(Function<Session, E> function) {
HibernateInvoker hibernateInvoker = HibernateInvoker.create(context.getSession());
Mode mode = Mode.create().with(new MutexSyncMode<>(context.getGuild().getIdLong(), GUILD_MUTEX_SYNC));
return hibernateInvoker.invokeFunction(mode, function);
}
use of net.robinfriedli.exec.Mode in project aiode by robinfriedli.
the class MessageService method executeMessageAction.
public CompletableFuture<Message> executeMessageAction(MessageChannel channel, Function<MessageChannel, MessageAction> function, Permission... additionalPermissions) {
CompletableFuture<Message> futureMessage = new CompletableFuture<>();
MESSAGE_DISPATCH_RATE_LIMITER.invokeLimited(EMPTY_MODE, () -> {
try {
if (channel instanceof TextChannel) {
TextChannel textChannel = (TextChannel) channel;
Guild guild = textChannel.getGuild();
Member selfMember = guild.getSelfMember();
if (!(selfMember.hasAccess(textChannel) && textChannel.canTalk(selfMember))) {
logger.warn(String.format("Can't execute message actions for channel %s on guild %s due to a lack of permissions", textChannel, guild));
futureMessage.cancel(false);
return;
}
for (Permission additionalPermission : additionalPermissions) {
if (!selfMember.hasPermission(textChannel, additionalPermission)) {
logger.warn(String.format("Can't execute message action for channel %s on guild %s due to missing permission %s", textChannel, guild, additionalPermission));
if (!ESSENTIAL_PERMISSIONS.contains(additionalPermission)) {
String message = "Bot is missing permission: " + additionalPermission.getName();
Mode mode = Mode.create().with(new RecursionPreventionMode("message_service_send_missing_permission_message"));
RECURSION_PREVENTION_INVOKER.invoke(mode, () -> {
send(message, channel);
});
}
futureMessage.cancel(false);
return;
}
}
}
MessageAction messageAction = function.apply(channel);
messageAction.timeout(10, TimeUnit.SECONDS).queue(futureMessage::complete, e -> {
handleError(e, channel);
futureMessage.completeExceptionally(e);
});
} catch (InsufficientPermissionException e) {
Permission permission = e.getPermission();
if (permission == Permission.MESSAGE_WRITE || permission == Permission.MESSAGE_READ) {
String msg = "Unable to send messages to channel " + channel;
if (channel instanceof TextChannel) {
msg = msg + " on guild " + ((TextChannel) channel).getGuild();
}
logger.warn(msg);
futureMessage.completeExceptionally(e);
} else {
StringBuilder errorMessage = new StringBuilder("Missing permission ").append(permission);
if (channel instanceof TextChannel) {
errorMessage.append(" on guild ").append(((TextChannel) channel).getGuild());
}
logger.warn(errorMessage.toString());
futureMessage.completeExceptionally(e);
if (permission != Permission.VIEW_CHANNEL) {
String message = "Bot is missing permission: " + permission.getName();
Mode mode = Mode.create().with(new RecursionPreventionMode("message_service_send_missing_permission_message"));
RECURSION_PREVENTION_INVOKER.invoke(mode, () -> {
send(message, channel);
});
}
}
}
});
return futureMessage;
}
Aggregations