Restlet client calls to Restlet server hang

I use Restlet to implement a web service. The client (also uses Restlet) makes many consecutive calls to the server, but after a small number of calls have completed successfully, further calls hang on the server on which the message is displayed:

INFO: Stop accepting new connections and transactions. Consider increasing the maximum number of threads.

I tried:

getContext().getParameters().add("maxThreads", "200"); 

but it doesn’t help. In any case, it seems that the client should be able to make an unlimited number of calls, and increasing maxThreads simply increases the limit. It seems that I am not releasing any resource or disconnecting after each client call, but I do not know how to do this.

The following (small how I could do this) stand-alone program demonstrates the problem. It starts a simple server, and then the client calls it a bunch of times:

 /** You may copy, modify, and re-use this code as you see fit - Jim Irrer */ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import org.restlet.Application; import org.restlet.Component; import org.restlet.Request; import org.restlet.Response; import org.restlet.Restlet; import org.restlet.Server; import org.restlet.data.MediaType; import org.restlet.data.Method; import org.restlet.data.Protocol; import org.restlet.data.Status; import org.restlet.representation.InputRepresentation; import org.restlet.representation.Representation; import org.restlet.resource.ClientResource; import org.restlet.resource.Directory; public class SimpleServerPut extends Component implements Runnable { private static final int PORT = 8080; private static int readToByteArray(InputStream inputStream, byte[] buf) throws IOException { int length = 0; int b; while ((b = inputStream.read()) != -1) { buf[length++] = (byte)b; } return length; } @Override public void run() { getContext().getParameters().add("maxThreads", "200"); // Create the HTTP server and listen on port PORT SimpleServerPut simpleServer = new SimpleServerPut(); Server server = new Server(Protocol.HTTP, PORT, simpleServer); simpleServer.getClients().add(Protocol.FILE); // Create an application Application application = new Application(simpleServer.getContext()) { @Override public Restlet createRoot() { return new Directory(getContext(), "C:"); } }; // Attach the application to the component and start it simpleServer.getDefaultHost().attach("/stuff/", application); try { server.start(); } catch (Exception ex) { ex.printStackTrace(); } } @Override public void handle(Request request, Response response) { // assume the worst response.setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED); response.setEntity("No no - Bad client! Only do PUTs.", MediaType.TEXT_PLAIN); try { if (request.getMethod() == Method.PUT) { InputStream inputStream = request.getEntity().getStream(); byte[] buf = new byte[64*1024]; int totalLength = readToByteArray(inputStream, buf); response.setStatus(Status.SUCCESS_OK); String msg = "Number of bytes received: " + totalLength; response.setEntity(msg, MediaType.TEXT_PLAIN); System.out.println("server: " + msg); return; } } catch (Exception ex) { ex.printStackTrace(); } } private static String callServer() throws IOException { String urlText = "http://localhost:" + PORT + "/"; ClientResource clientResource = new ClientResource(urlText); clientResource.setReferrerRef(urlText); byte[] buf = new byte[1000]; for (int i = 0; i < buf.length; i++) { buf[i] = (byte)((int)'a' + (i%26)); } ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(buf); Representation representation = new InputRepresentation(byteArrayInputStream, MediaType.APPLICATION_OCTET_STREAM); Representation representation2 = clientResource.put(representation); byte[] responseBuf = new byte[16*1024]; int length = readToByteArray(representation2.getStream(), responseBuf); Response response = clientResource.getResponse(); Status status = response.getStatus(); return "status: " + status + " message: " + new String(responseBuf, 0, length); } // Start server and call it a bunch of times public static void main(String[] args) throws Exception { SimpleServerPut simpleServer = new SimpleServerPut(); new Thread(simpleServer).start(); Thread.sleep(200); // cheap trick to make sure that server is running // make a bunch of client calls for (int t = 0; t < 100; t++) { System.out.println("client count: " + (t+1) + " " + callServer()); } System.exit(0); } } 
+6
source share
4 answers

We were able to solve this problem by stopping directly the client associated with ClientResource (using Restlet version 2.0.15):

 Client c = (Client)clientResource.getNext(); try { c.stop(); } catch (Exception e) { //handle exception } 
+5
source

Add a line so that the client releases the resource:

  Response response = clientResource.getResponse(); Status status = response.getStatus(); clientResource.release(); // add this line 

for the client, and everything works. In the end, the server expires if the client dies, but it takes some time.

+4
source

I solved the problem by downloading the latest stable version of Restlet API

Obviously, the .jar I used was an old version where the release() command has no effect.

Before the upgrade, the client log displays only the beginning of the client:

 Sep 05, 2012 9:50:19 AM org.restlet.engine.http.connector.HttpClientHelper start INFO: Starting the default HTTP client 

Now it also displays a stop:

 Sep 05, 2012 9:50:19 AM org.restlet.engine.http.connector.HttpClientHelper stop INFO: Stopping the default HTTP client 
+1
source

In addition to calling ClientResource.release (), you can call exit () to submit.

 Representation responseRepresentation = response.getEntity(); if (responseRepresentation != null) { try { responseRepresentation.exhaust(); } catch (IOException e) { // handle exception } responseRepresentation.release(); } 

Related discussion in this thread .

0
source

Source: https://habr.com/ru/post/902245/


All Articles