Search in sources :

Example 1 with Mode

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;
        });
    });
}
Also used : QueryBuilderFactory(net.robinfriedli.aiode.persist.qb.QueryBuilderFactory) Mode(net.robinfriedli.exec.Mode) MutexSyncMode(net.robinfriedli.exec.modes.MutexSyncMode)

Example 2 with Mode

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);
}
Also used : HibernateInvoker(net.robinfriedli.aiode.function.HibernateInvoker) MutexSyncMode(net.robinfriedli.exec.modes.MutexSyncMode) Mode(net.robinfriedli.exec.Mode)

Example 3 with Mode

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);
}
Also used : HibernateInvoker(net.robinfriedli.aiode.function.HibernateInvoker) MutexSyncMode(net.robinfriedli.exec.modes.MutexSyncMode) Mode(net.robinfriedli.exec.Mode)

Example 4 with Mode

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;
}
Also used : Message(net.dv8tion.jda.api.entities.Message) RecursionPreventionMode(net.robinfriedli.aiode.function.modes.RecursionPreventionMode) Mode(net.robinfriedli.exec.Mode) InsufficientPermissionException(net.dv8tion.jda.api.exceptions.InsufficientPermissionException) Guild(net.dv8tion.jda.api.entities.Guild) RecursionPreventionMode(net.robinfriedli.aiode.function.modes.RecursionPreventionMode) CompletableFuture(java.util.concurrent.CompletableFuture) TextChannel(net.dv8tion.jda.api.entities.TextChannel) MessageAction(net.dv8tion.jda.api.requests.restaction.MessageAction) Permission(net.dv8tion.jda.api.Permission) Member(net.dv8tion.jda.api.entities.Member)

Aggregations

Mode (net.robinfriedli.exec.Mode)4 MutexSyncMode (net.robinfriedli.exec.modes.MutexSyncMode)3 HibernateInvoker (net.robinfriedli.aiode.function.HibernateInvoker)2 CompletableFuture (java.util.concurrent.CompletableFuture)1 Permission (net.dv8tion.jda.api.Permission)1 Guild (net.dv8tion.jda.api.entities.Guild)1 Member (net.dv8tion.jda.api.entities.Member)1 Message (net.dv8tion.jda.api.entities.Message)1 TextChannel (net.dv8tion.jda.api.entities.TextChannel)1 InsufficientPermissionException (net.dv8tion.jda.api.exceptions.InsufficientPermissionException)1 MessageAction (net.dv8tion.jda.api.requests.restaction.MessageAction)1 RecursionPreventionMode (net.robinfriedli.aiode.function.modes.RecursionPreventionMode)1 QueryBuilderFactory (net.robinfriedli.aiode.persist.qb.QueryBuilderFactory)1