Simplify threading and networking in download suggester (#1512)
* Simplify threading in download suggester This also makes it more robust against race conditions * Simplify network requests around app store
This commit is contained in:
1 parent
c08d857821
commit
97c4cc9c7d
1 file changed
+7
-58
@@ -18,14 +18,9 @@ import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.commands.CommandRuntimeException;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.world.level.storage.LevelResource;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -36,9 +31,10 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
/**
|
||||
* A class used to save scarpet app store scripts to disk
|
||||
*/
|
||||
@@ -85,7 +81,6 @@ public class AppStoreManager
|
||||
public Map<String, StoreNode> children;
|
||||
public boolean sealed;
|
||||
public String value;
|
||||
private CountDownLatch childrenProgress;
|
||||
public static StoreNode folder(StoreNode parent, String name)
|
||||
{
|
||||
StoreNode node = new StoreNode(parent, name);
|
||||
@@ -127,38 +122,23 @@ public class AppStoreManager
|
||||
this.sealed = false;
|
||||
}
|
||||
|
||||
public void fillChildren() throws IOException
|
||||
public synchronized void fillChildren() throws IOException
|
||||
{
|
||||
if (sealed) return;
|
||||
if (scarpetRepoLink == null) throw new IOException("Accessing scarpet app repo is disabled");
|
||||
try
|
||||
{
|
||||
if (childrenProgress != null)
|
||||
{
|
||||
childrenProgress.await();
|
||||
if (sealed) return;
|
||||
else throw new IOException("Problems fetching suggestions. Check more details in previous exceptions.");
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
throw new IOException("Suggestion provider thread was interrupted, unexpected!", e);
|
||||
}
|
||||
childrenProgress = new CountDownLatch(1);
|
||||
|
||||
String queryPath = scarpetRepoLink + getPath();
|
||||
String response;
|
||||
try
|
||||
{
|
||||
response = AppStoreManager.getStringFromStream(queryPath);
|
||||
response = IOUtils.toString(new URL(queryPath), StandardCharsets.UTF_8);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
childrenProgress.countDown();
|
||||
childrenProgress = null; // Reset to allow retrying
|
||||
// Not sealing to allow retrying
|
||||
throw new IOException("Problems fetching " + queryPath, e);
|
||||
}
|
||||
JsonArray files = new JsonParser().parse(response).getAsJsonArray();
|
||||
JsonArray files = JsonParser.parseString(response).getAsJsonArray();
|
||||
for(JsonElement je : files)
|
||||
{
|
||||
JsonObject jo = je.getAsJsonObject();
|
||||
@@ -174,7 +154,6 @@ public class AppStoreManager
|
||||
}
|
||||
}
|
||||
sealed = true;
|
||||
childrenProgress.countDown();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -265,7 +244,7 @@ public class AppStoreManager
|
||||
String code;
|
||||
try
|
||||
{
|
||||
code = getStringFromStream(nodeInfo.url());
|
||||
code = IOUtils.toString(new URL(nodeInfo.url()), StandardCharsets.UTF_8);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
@@ -350,36 +329,6 @@ public class AppStoreManager
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Returns the string from the inputstream gotten from the html request.
|
||||
* Thanks to App Shah in <a href="https://crunchify.com/in-java-how-to-read-github-file-contents-using-httpurlconnection-convert-stream-to-string-utility/">this post</a>
|
||||
* for this code.
|
||||
*
|
||||
* @return the string input from the InputStream
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
public static String getStringFromStream(String url) throws IOException
|
||||
{
|
||||
InputStream inputStream = new URL(url).openStream();
|
||||
if (inputStream == null)
|
||||
throw new IOException("No app to be found on the appstore");
|
||||
|
||||
Writer stringWriter = new StringWriter();
|
||||
char[] charBuffer = new char[2048];
|
||||
try
|
||||
{
|
||||
Reader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
int counter;
|
||||
while ((counter = reader.read(charBuffer)) != -1)
|
||||
stringWriter.write(charBuffer, 0, counter);
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
inputStream.close();
|
||||
}
|
||||
return stringWriter.toString();
|
||||
}
|
||||
|
||||
public static void writeUrlToFile(String url, Path destination) throws IOException
|
||||
{
|
||||
try (final InputStream in = new URL(url).openStream())
|
||||
|
||||
Reference in new issue
Block a user