Put some limits on various external queues

Ideally turtle functions would error, but wrangling that is more pain
than it's worth.
This commit is contained in:
Jonathan Coates 2021-06-06 19:26:20 +01:00
parent 29cc5bb86b
commit 026afa7f73
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
6 changed files with 20 additions and 17 deletions

View File

@ -7,9 +7,6 @@
<suppress checks="StaticVariableName" files=".*[\\/]ComputerCraft.java" /> <suppress checks="StaticVariableName" files=".*[\\/]ComputerCraft.java" />
<suppress checks="StaticVariableName" files=".*[\\/]ComputerCraftAPI.java" /> <suppress checks="StaticVariableName" files=".*[\\/]ComputerCraftAPI.java" />
<!-- Do not check for missing package Javadoc. -->
<suppress checks="JavadocStyle" files=".*[\\/]package-info.java" />
<!-- The commands API is documented in Lua. --> <!-- The commands API is documented in Lua. -->
<suppress checks="SummaryJavadocCheck" files=".*[\\/]CommandAPI.java" /> <suppress checks="SummaryJavadocCheck" files=".*[\\/]CommandAPI.java" />
</suppressions> </suppressions>

View File

@ -37,7 +37,7 @@ public class HTTPAPI implements ILuaAPI
{ {
private final IAPIEnvironment apiEnvironment; private final IAPIEnvironment apiEnvironment;
private final ResourceGroup<CheckUrl> checkUrls = new ResourceGroup<>(); private final ResourceGroup<CheckUrl> checkUrls = new ResourceGroup<>( ResourceGroup.DEFAULT );
private final ResourceGroup<HttpRequest> requests = new ResourceQueue<>( () -> ComputerCraft.httpMaxRequests ); private final ResourceGroup<HttpRequest> requests = new ResourceQueue<>( () -> ComputerCraft.httpMaxRequests );
private final ResourceGroup<Websocket> websockets = new ResourceGroup<>( () -> ComputerCraft.httpMaxWebsockets ); private final ResourceGroup<Websocket> websockets = new ResourceGroup<>( () -> ComputerCraft.httpMaxWebsockets );
@ -127,7 +127,10 @@ public final Object[] request( IArguments args ) throws LuaException
HttpRequest request = new HttpRequest( requests, apiEnvironment, address, postString, headers, binary, redirect ); HttpRequest request = new HttpRequest( requests, apiEnvironment, address, postString, headers, binary, redirect );
// Make the request // Make the request
request.queue( r -> r.request( uri, httpMethod ) ); if( !request.queue( r -> r.request( uri, httpMethod ) ) )
{
throw new LuaException( "Too many ongoing HTTP requests" );
}
return new Object[] { true }; return new Object[] { true };
} }
@ -138,12 +141,15 @@ public final Object[] request( IArguments args ) throws LuaException
} }
@LuaFunction @LuaFunction
public final Object[] checkURL( String address ) public final Object[] checkURL( String address ) throws LuaException
{ {
try try
{ {
URI uri = HttpRequest.checkUri( address ); URI uri = HttpRequest.checkUri( address );
new CheckUrl( checkUrls, apiEnvironment, address, uri ).queue( CheckUrl::run ); if( !new CheckUrl( checkUrls, apiEnvironment, address, uri ).queue( CheckUrl::run ) )
{
throw new LuaException( "Too many ongoing checkUrl calls" );
}
return new Object[] { true }; return new Object[] { true };
} }

View File

@ -97,7 +97,7 @@ public final void close()
tryClose(); tryClose();
} }
public boolean queue( Consumer<T> task ) public final boolean queue( Consumer<T> task )
{ {
@SuppressWarnings( "unchecked" ) @SuppressWarnings( "unchecked" )
T thisT = (T) this; T thisT = (T) this;

View File

@ -18,6 +18,9 @@
*/ */
public class ResourceGroup<T extends Resource<T>> public class ResourceGroup<T extends Resource<T>>
{ {
public static final int DEFAULT_LIMIT = 512;
public static final IntSupplier DEFAULT = () -> DEFAULT_LIMIT;
private static final IntSupplier ZERO = () -> 0; private static final IntSupplier ZERO = () -> 0;
final IntSupplier limit; final IntSupplier limit;

View File

@ -38,8 +38,10 @@ public synchronized void shutdown()
public synchronized boolean queue( Supplier<T> resource ) public synchronized boolean queue( Supplier<T> resource )
{ {
if( !active ) return false; if( !active ) return false;
if( super.queue( resource ) ) return true;
if( pending.size() > DEFAULT_LIMIT ) return false;
if( !super.queue( resource ) ) pending.add( resource ); pending.add( resource );
return true; return true;
} }

View File

@ -503,20 +503,15 @@ public void addFuel( int fuel )
setFuelLevel( getFuelLevel() + addition ); setFuelLevel( getFuelLevel() + addition );
} }
private int issueCommand( ITurtleCommand command )
{
commandQueue.offer( new TurtleCommandQueueEntry( ++commandsIssued, command ) );
return commandsIssued;
}
@Nonnull @Nonnull
@Override @Override
public MethodResult executeCommand( @Nonnull ITurtleCommand command ) public MethodResult executeCommand( @Nonnull ITurtleCommand command )
{ {
if( getWorld().isClientSide ) throw new UnsupportedOperationException( "Cannot run commands on the client" ); if( getWorld().isClientSide ) throw new UnsupportedOperationException( "Cannot run commands on the client" );
if( commandQueue.size() > 16 ) return MethodResult.of( false, "Too many ongoing turtle commands" );
// Issue command commandQueue.offer( new TurtleCommandQueueEntry( ++commandsIssued, command ) );
int commandID = issueCommand( command ); int commandID = commandsIssued;
return new CommandCallback( commandID ).pull; return new CommandCallback( commandID ).pull;
} }