-
Notifications
You must be signed in to change notification settings - Fork 18
Open
Labels
enhancementNew feature or requestNew feature or request
Description
Currently, if an HTTP endpoint (e.g. a Spring Controller) uses an ExecutorService
to run a task, none of that processing shows up in the AppMap. For example:
@DeleteMapping("dolphins")
public String dolphins() throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newCachedThreadPool();
Future<Object> future1 = executorService.submit((Callable<Object>)() -> {
DolphinChat dc = new DolphinChat();
dc.say("So");
dc.say("long,");
});
Future<Object> future2 = executorService.submit((Callable<Object>)() -> {
DolphinChat dc = new DolphinChat();
dc.say("and thanks for");
dc.say("all the fish");
});
NextUp nu = new NextUp();
nu.say("Mostly Harmless");
return future1.get() + " " + future2.get();
}
the calls to DolphinChat
methods won't show up in the AppMap.
Instead, the (pseudo) events should look like this:
{http_server_request, thread: 1}
{call, method: ExecutorService.submit, thread:1}
{call, method: Runnable.run, thread: 1, task:true}
{call, method: DolphinChat.say("So"), thread: 1}
{return, parent: DolphinChat.say, thread: 1}
{call, method: DolphinChat.say("long"), thread: 1}
{return, parent: DolphinChat.say, thread: 1}
{return, parent:Runnable.run, thread: 1}
{return, parent: ExecutorService.submit, thread: 1} // when get is called on the Future returned by submit
{call, method: ExecutorService.submit, thread:1}
{call, method: Runnable.run, thread: 1, task:true}
{call, method: DolphinChat.say("and thanks for"), thread: 1}
{return, parent: DolphinChat.say, thread: 1}
{call, method: DolphinChat.say("all the fish"), thread: 1}
{return, parent: DolphinChat.say, thread: 1}
{return, parent:Runnable.run, thread: 1}
{return, parent: ExecutorService.submit, thread: 1} // when get is called on the Future returned by submit
{call, method: NextUp.say("Mostly Harmless"), thread: 1}
{return, parent: NextUp.say, thread: 1}
{http_server_response, thread: 1}
This says they all have the same thread id (that matches the thread that creates the ExecutorService
). The ordering of the call
and return
events show that the calls to DolphinChat.say
happened in a Runnable
/Callable
submitted to an ExecutorService
. Note that the order of the complete Runnable.run
call chains may not match the order in the code, of course, because they were run on separate threads.
Test cases:
- end-to-end, for an endpoint like
dolphins
, generates an AppMap - checkpoint is disabled once
ExecutorService.submit
has been called - classes referenced only in a task show up in the classmap of the final AppMap
- both a
Callable
andRunnable
passed toExecutorService.submit
are handled correctly - process recording for a call to
dolphins
generates an AppMap - remote recording that spans a call to the
dolphins
endpoint generates an AppMap - task recording stops when
Future.cancel
is called. [What should happen to the task's recording?] - task recording stops when the method that called
ExecutorService.submit
returns. [What should happen if there are outstandingFuture
s?]
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request