Upgrade to Pro — share decks privately, control downloads, hide ads and more …

一体いつから ――― DataLoader が 並列実行されていると錯覚していた?

Avatar for SMS tech SMS tech
June 24, 2025
59

一体いつから ――― DataLoader が 並列実行されていると錯覚していた?

Avatar for SMS tech

SMS tech

June 24, 2025
Tweet

More Decks by SMS tech

Transcript

  1. 0 © SMS Co., Ltd. 2025.06.25 【非公式】 JJUG CCC 2025

    Spring 後夜祭 LT 株式会社エス・エム・エス プロダクト推進本部 @hmarui66 一体いつから ――― DataLoader が 並列実行されていると錯覚していた?
  2. 2 © SMS Co., Ltd. Spring for GraphQL 使ってます アノテーションでスキーマとマッピング

    (プラグイン入れたら ✡アイコンで相互にジャンプ可能)
  3. 3 © SMS Co., Ltd. Spring for GraphQL 使ってます `@BatchMapping`

    は暗黙的に DataLoader を 使用して N+1 問題を回避してくれる(便利) 参考: https://spring.pleiades.io/spring-graphql/reference/controllers.html#controllers.batch-mapping
  4. 11 © SMS Co., Ltd. クエリ処理の流れ (このサンプルでは) `publisher` → `author`

    と直列で実行 ※OpenTelemetry の Java Agent を仕込んで可視化
  5. 13 © SMS Co., Ltd. 並列実行するには Java 21+ では、AnnotatedControllerConfigurer が

    Executor で構成されている場合、 ブロッキングメソッドシグネチャーを持つコントローラーメソッドが 非同期的に呼び出されます。 ドキュメントによると... 参考: https://spring.pleiades.io/spring-graphql/reference/controllers.html#controllers.schema-mapping.return.values → AnnotatedControllerConfigurer をカスタムすればいけそう
  6. 16 © SMS Co., Ltd. 実はドキュメントには、こうも書かれている 並列実行するには Spring for GraphQL

    の Spring Boot スターターは、 プロパティ spring.threads.virtual.enabled が設定されている場合、仮想スレッドの Executor を使 用して AnnotatedControllerConfigurer を自動的に構成します。 参考: https://spring.pleiades.io/spring-graphql/reference/controllers.html#controllers.schema-mapping.return.values → Virtual Threads を有効化すると自動的に非同期実行!!!
  7. 18 © SMS Co., Ltd. 実はデフォルトでも AnnotatedControllerConfigure の Executor はセットされている

    ちょっと込み入った話 参考: https://github.com/spring-projects/spring-boot/blob/740362d3941a0952a7e92183a96c9ef28ef46de0/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/spri ngframework/boot/autoconfigure/task/TaskExecutorConfigurations.java#L59-L65 https://github.com/spring-projects/spring-boot/blob/740362d3941a0952a7e92183a96c9ef28ef46de0/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/spri ngframework/boot/autoconfigure/graphql/GraphQlAutoConfiguration.java#L155-L166
  8. 19 © SMS Co., Ltd. AnnotatedControllerConfigure の DataLoader の設定箇所の `shouldInvokeAsync`

    に注目 ちょっと込み入った話 参考: https://github.com/spring-projects/spring-graphql/blob/7ee16217f76fc92240e89ee781607acf3ca0981c/spring-graphql/src/main/java/org/springframework/graphql/data/m ethod/annotation/support/AnnotatedControllerConfigurer.java#L346-L393 https://github.com/spring-projects/spring-graphql/blob/7ee16217f76fc92240e89ee781607acf3ca0981c/spring-graphql/src/main/java/org/springframework/graphql/data/m ethod/annotation/support/AnnotatedControllerDetectionSupport.java#L302-L305 「Executor が SchedulingTaskExecutor && prefersShortLivedTasks が true」ではない場合、非 同期で実行される
  9. 20 © SMS Co., Ltd. デフォルトの Executor の設定箇所、再掲 ちょっと込み入った話 ここで

    build される ThreadPoolTaskExecutor は SchedulingTaskExecutor を実装。 そして、SchedulingTaskExecutor は prefersShortLivedTasks を true 固定。 →前のページの `shouldInvokeAsync` が false となり、非同期実行されず直列処理
  10. 21 © SMS Co., Ltd. リポジトリを見ると Virtual Threads 対応はされてい る...?🤔

    参考: https://github.com/DataDog/dd-trace-java/pull/6789 Virtual Threads を有効にすると Datadog の javaagent でトレースが途切れる問題がある。 ※dd-java-agent-1.49.0 現在 ちょっと込み入った話 2
  11. 22 © SMS Co., Ltd. 参考: https://github.com/spring-projects/spring-boot/blob/740362 d3941a0952a7e92183a96c9ef28ef46de0/spring-boot-proje ct/spring-boot-autoconfigure/src/main/java/org/springframe work/boot/autoconfigure/task/TaskExecutorConfigurations.j

    ava#L52-L57 参考: https://github.com/DataDog/dd-trace-java/blob/56844c2a3f b79bb9ece1f6a9078bb36e9e7d3939/dd-java-agent/instru mentation/java-concurrent/src/main/java/datadog/trace/inst rumentation/java/concurrent/TaskRunnerInstrumentation.ja va#L27-L30 Virtual Threads サポートの PR での計装対象は `ThreadPerTaskExecutor` だが... ちょっと込み入った話 2 Spring の AutoConfigure はデフォルトで `SimpleAsyncTaskExecutor` を設定してる →計装漏れにつながってそう? ※AnnotatedControllerConfigurer#setExecutor に Executors.newVirtualThreadPerTaskExecutor() を渡したら 途切れなかったので、そうっぽい