Class ServiceBeansConfig

java.lang.Object
ubic.gemma.core.config.ServiceBeansConfig

@Configuration public class ServiceBeansConfig extends Object
Phase 3 XML->Java migration: replaces the default-profile beans from applicationContext-serviceBeans.xml — entityUrlBuilder, taskExecutor, and expressionDataFileTaskExecutor.

Bean ids are preserved exactly because other code (XML wiring elsewhere, @Qualifier references, and applicationContext.getBean("taskExecutor") call sites) resolves them by name.

The metrics profile beans from the original XML are migrated separately in MetricsConfig. The dead MeterRegistryEhcacheConfigurer bean (whose backing class was removed in the Phase 2 EhCache retirement) is intentionally not carried over — the metrics profile is opt-in and was never being instantiated anyway.

  • Constructor Details

    • ServiceBeansConfig

      public ServiceBeansConfig()
  • Method Details

    • entityUrlBuilder

      @Bean @Primary public EntityUrlBuilder entityUrlBuilder(@Value("${gemma.hosturl}") String hostUrl)
      Marked Primary because gsec's XML also defines an entityUrlBuilder bean (with a different host-url source); the legacy XML used primary="true" so that Gemma's host-url-configured builder wins over gsec's at injection sites that ask for the type without qualifier.
    • taskExecutor

      @Bean(name="taskExecutor") @Primary public org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor taskExecutor(@Value("${gemma.localTasks.corePoolSize}") int corePoolSize)
      Local short-lived task executor. Marked Primary so that injection points asking for TaskExecutor (without a qualifier) get this one rather than expressionDataFileTaskExecutor.
    • expressionDataFileTaskExecutor

      @Bean(name="expressionDataFileTaskExecutor") public ServiceBeansConfig.DrainingTaskExecutor expressionDataFileTaskExecutor(VirtualThreadExecutorMetrics expressionDataFileTaskExecutorMetrics, @Value("${gemma.expressionDataFileTasks.shutdownTimeoutSeconds:60}") int shutdownTimeoutSeconds)
      Executor for generating data files (CEL / count matrices / TSVs).

      JDK 21 migration: backed by a virtual-thread-per-task executor wrapped through Spring's ConcurrentTaskExecutor so it still implements AsyncTaskExecutor (callers execute/submit via that interface).

      Behavioural change vs. the previous ThreadPoolTaskExecutor: submission never blocks and never throws TaskRejectedException, because there is no bounded queue and no fixed worker pool. Concurrency is bounded only by the number of in-flight VTs the JVM is willing to mount. The gemma.expressionDataFileTasks.corePoolSize and .queueCapacity properties no longer constrain this executor. The two consumers (DifferentialExpressionAnalyzerServiceImpl, ExpressionDataFileServiceImpl) both treat TaskRejectedException as a soft failure ("archive will be rebuilt on next read"), so dropping queue-based backpressure is safe.

      Pending tasks are waited for when the context closes, for at most gemma.expressionDataFileTasks.shutdownTimeoutSeconds; see ServiceBeansConfig.DrainingTaskExecutor.

    • expressionDataFileTaskExecutorMetrics

      @Bean public VirtualThreadExecutorMetrics expressionDataFileTaskExecutorMetrics()
      Micrometer binder for the expressionDataFileTaskExecutor(VirtualThreadExecutorMetrics, int) VT executor. Picked up by MetricsConfig#genericMeterRegistryConfigurer when the metrics profile is active. Defined as its own bean so the wrap-with-metrics path is exercised regardless of profile (a no-op bindTo when no registry is calling it).