Error cleaning up agent threads using okhttp3 in HCL Domino agent

140 Views Asked by At

I am using okhttp3 in an Notes Agent and every time it runs I get the message "Error cleaning up agent threads" in the console.

I get the same message if I run the agent in Notes 14 client or on the Domino server 12.02.FP2. the jar files are in the jar design object

enter image description here

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class JavaAgent extends AgentBase {

    OkHttpClient client;
    public void NotesMain() {

        try {
            Session session = getSession();
            AgentContext agentContext = session.getAgentContext();
    
            client = new OkHttpClient();
            Response response = null;
            Request request = new Request.Builder().url("https://www.cnn.com").build();

            try {
                response = client.newCall(request).execute();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (response != null) {
                    response.close();
                }
            }
    
        } catch (Exception e) {
            e.printStackTrace();
        }
    
    }

}

how can I resolve this error?

Here is an updated try based on comments:

try {
            Session session = getSession();
            AgentContext agentContext = session.getAgentContext();
            Response response = null;
            try {
    
                client = new OkHttpClient();
                Request request = new Request.Builder().url("https://www.cnn.com").build();
                response = client.newCall(request).execute();

                System.out.println("isTerminated: " + client.dispatcher().executorService().isTerminated());
                System.out.println("isShutDown: " + client.dispatcher().executorService().isShutdown());
                System.out.println("Calling ShutDownNow");
                client.dispatcher().executorService().shutdownNow();
                System.out.println("isTerminated: " + client.dispatcher().executorService().isTerminated());
                System.out.println("isShutDown: " + client.dispatcher().executorService().isShutdown());
                
                dumptg(null);
                
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (response != null) {
                    response.close();
                }
            }
    
        } catch (Exception e) {
            e.printStackTrace();
        }


Result:

 isTerminated: false
    isShutDown: false
    Calling ShutDownNow
    isTerminated: true
    isShutDown: true
    ThreadGroup UTG: JavaAgent, objid = -728930514
      subgroups  = 0
      total threads = 6
    
    Thread Name, ThreadID, ThreadGroup
    OkHttp TaskRunner, 1876182108, UTG: JavaAgent
    OkHttp TaskRunner, -536891291, UTG: JavaAgent
    Okio Watchdog, 511103762, UTG: JavaAgent
    OkHttp TaskRunner, -485203566, UTG: JavaAgent
    OkHttp www.cnn.com, -1274389829, UTG: JavaAgent
    AgentThread: JavaAgent, 201675379, UTG: JavaAgent
    Error cleaning up agent threads
1

There are 1 best solutions below

7
Mati Ustav On

Edit: it looks like OkHttp3 has the shutdown function that can be used directly. After your code is done, call client.dispatcher().executorService().shutdown(); in a finally block. You may experiment with shutdownNow() instead of shutdown() and may need to add awaitTermination().

You don't need the below code for OkHttp, but I'm leaving if here as a generic method.

--

IME if new threads are created in code running in an agent, they must be cleaned up before agend ends or you get that exact error message. Ignoring this message long enough will bring the server down.

If you use some third party thing that creates new threads, but doesn't clean them up, you could investigate to find out if you can provide your own threads and do the cleanup yourself.

I don't know okhttp3 or if there is a way with okhttp3, but something like this has worked fine for years with a particular third party library, in agents running on Domino v9 to v12:

ExecutorService executorService = null;
try {
  Thing thing = Thing.getInstance();
  if (thing.hasThingsToDo()) {
    executorService = Executors.newFixedThreadPool(4);
    thing.setThreadExecutor(executorService);
    thing.doThings();
  }
} finally {
  if (executorService != null) {
    executorService.shutdownNow();
    executorService.awaitTermination(3, TimeUnit.SECONDS);
  }
}

PS. It's more complicated in XPages, but can be done there too.