Skip to content

Commit

Permalink
misc: Better skin request batching, without creating new threads
Browse files Browse the repository at this point in the history
  • Loading branch information
MATRIX-feather committed Oct 20, 2024
1 parent dfd29b0 commit c0f2f17
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 119 deletions.
2 changes: 0 additions & 2 deletions src/main/java/xyz/nifeather/morph/MorphPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,6 @@ public void onDisable()
if (instanceService != null)
instanceService.onDisable();

PlayerSkinProvider.getInstance().shutdown();

var messenger = this.getServer().getMessenger();

messenger.unregisterOutgoingPluginChannel(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.mojang.authlib.ProfileLookupCallback;
import com.mojang.authlib.exceptions.AuthenticationUnavailableException;
import com.mojang.authlib.yggdrasil.ProfileNotFoundException;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import it.unimi.dsi.fastutil.objects.ObjectLists;
import net.minecraft.Util;
Expand Down Expand Up @@ -57,46 +58,18 @@ private void load()

// region Info Request Batching

private final List<String> namesToLookup = new ObjectArrayList<>();
private final Map<String, Optional<GameProfile>> batchResults = new ConcurrentHashMap<>();

// name <-> lock
private final Map<String, Object> nameLockMap = new ConcurrentHashMap<>();
private final Map<String, CompletableFuture<Optional<GameProfile>>> namesToLookup = new ConcurrentHashMap<>();

private CompletableFuture<Optional<GameProfile>> fetchPlayerInfoAsync(String name)
{
var executor = ProfileLookupExecutor.executor();

return CompletableFuture.supplyAsync(() -> this.schedulePlayerInfo(name), executor);
}
var future = new CompletableFuture<Optional<GameProfile>>();

private Optional<GameProfile> schedulePlayerInfo(String name)
{
synchronized (namesToLookup)
synchronized (batchLock)
{
this.namesToLookup.add(name);
this.namesToLookup.put(name, future);
}

var lock = new Object();
nameLockMap.put(name.toUpperCase(), lock);

try
{
synchronized (lock)
{
lock.wait();
}

if (!this.batchResults.containsKey(name))
return Optional.empty();
else
return this.batchResults.remove(name);
}
catch (InterruptedException e)
{
logger.info("Skin lookup request for '%s' canceled by external source".formatted(name));
return Optional.empty();
}
return future;
}

private static final Object batchLock = new Object();
Expand All @@ -116,35 +89,26 @@ private void startBatchPlayerInfo()
{
if (namesToLookup.isEmpty()) return;

List<String> list;
Map<String, CompletableFuture<Optional<GameProfile>>> toBatch;
synchronized (namesToLookup)
{
list = namesToLookup.stream().map(String::toUpperCase).toList();
toBatch = new Object2ObjectOpenHashMap<>(this.namesToLookup);
namesToLookup.clear();
}

List<String> remainingNames = new ObjectArrayList<>(list);
List<String> remainingNames = new ObjectArrayList<>(toBatch.keySet());

BiConsumer<String, @Nullable GameProfile> onRequestFinish = (n, profile) ->
BiConsumer<String, @Nullable GameProfile> onRequestFinish = (name, profile) ->
{
var nameUpper = n.toUpperCase();

Optional<GameProfile> optional = profile == null ? Optional.empty() : Optional.of(profile);
this.batchResults.put(n, optional);

remainingNames.remove(nameUpper);

var lock = nameLockMap.remove(nameUpper);
if (lock == null)
{
//logger.warn(nameUpper + ": Don't have a lock?!");
return;
}
remainingNames.remove(name);

synchronized (lock)
{
lock.notifyAll();
}
var future = toBatch.getOrDefault(name, null);
if (future == null)
logger.warn("Profile with name '%s' configured a lookup request but no callback is set?!");
else
future.complete(optional);
};

var lookupCallback = new ProfileLookupCallback()
Expand Down Expand Up @@ -314,10 +278,5 @@ public void invalidate(String name)
skin.expiresAt = 0;
}

public void shutdown()
{
ProfileLookupExecutor.executor().shutdownNow();
}

//endregion
}

This file was deleted.

0 comments on commit c0f2f17

Please sign in to comment.