getappmap / getappmap/appmap-java
Recordings show when control is transferred into a thread by an ExecutorService
@apotterri đang làm issue này rồi.
Từ ngày 20/3/2024.
- Ngôn ngữ chính
- Java
- Star
- 88
- Fork
- 17
- Merge trung bình
- 2 ngày 2 giờ
- Pull request đã merge (30 ngày)
- 1
Mô tả
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.submithas been called - classes referenced only in a task show up in the classmap of the final AppMap
- both a
CallableandRunnablepassed toExecutorService.submitare handled correctly - process recording for a call to
dolphinsgenerates an AppMap - remote recording that spans a call to the
dolphinsendpoint generates an AppMap - task recording stops when
Future.cancelis called. [What should happen to the task's recording?] - task recording stops when the method that called
ExecutorService.submitreturns. [What should happen if there are outstandingFutures?]
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Đánh giá
Issue này chưa được đánh giá.