🚨 Issue: Warnings triggered when generating ComplexHeatmap inside future_promise()
Labels: bug parallel ComplexHeatmap future
Component: RNAseqShinyApp – Heatmap Rendering Module
🧾 Summary
When executing make_heatmap_mae() inside future_promise() (with multisession plan), several warnings and messages are triggered at runtime:
🔍 Full warning message
'use_raster' is automatically set to TRUE for a matrix with more than 2000 rows.
'magick' package is suggested to install to give better rasterization.
The automatically generated colors map from the 1^st and 99^th of the values in the matrix.
You can manually set the color to `col` argument.
Warning: MultisessionFuture (NULL) added, removed, or modified devices.
A future expression must close any opened devices and must not close devices it did not open.
Warning: UNRELIABLE VALUE: Future (NULL) unexpectedly generated random numbers
without specifying argument 'seed'. There is a risk that those random numbers are not statistically sound
and the overall results might be invalid. To fix this, specify 'seed=TRUE'.
[2025-04-18 06:08:26.109379] initialize the original heatmap (ID: ht) and calculate positions.
[1] "not saving the figure"
🧭 Root Cause Analysis
| Message / Warning |
Cause |
Problem |
use_raster, magick, color scale notices |
Informational from ComplexHeatmap |
Cosmetic only |
⚠️ devices differ |
draw() is called inside future_promise() → opens graphics device in worker |
Device not closed in correct thread; causes leakage/mismatch |
⚠️ UNRELIABLE VALUE |
Random numbers generated in worker without seed |
Results non-reproducible |
🧪 Current Behavior
future_promise({
make_heatmap_mae(mae, geneListVec) # internally calls draw()
on.exit(dev.off()) # may or may not close the right device
}, seed = TRUE) %...>% (function(ht) {
if (!is.null(ht)) {
makeInteractiveComplexHeatmap(input, output, session, ht, "ht")
} else {
output$ht_heatmap <- renderPlot({
grid::grid.text("No data available.")
})
}
})
✅ Recommended Fix
# Inside make_heatmap_mae()
if (isTRUE(draw_ht)) {
ht <- draw(ht, merge_legend = TRUE)
}
return(ht)
future_promise({
make_heatmap_mae(mae, geneListVec, draw_ht = FALSE)
}, seed = TRUE) %...>% (function(ht) {
makeInteractiveComplexHeatmap(
input, output, session,
ComplexHeatmap::draw(ht, merge_legend = TRUE),
heatmap_id = "ht"
)
})
ComplexHeatmap::ht_opt$message <- FALSE
✅ Acceptance Criteria
🧩 Notes
- Drawing plots inside parallel workers (via
draw()) opens graphics devices outside the main R session, which is unsafe.
- Random number generation in parallel processes requires explicit
seed = TRUE to ensure reproducibility.
- Returning a
draw()-free Heatmap object significantly reduces serialization size and improves performance.
- If a static plot is needed, consider returning a PNG path instead, or rendering with
renderImage().
🚨 Issue: Warnings triggered when generating ComplexHeatmap inside
future_promise()Labels:
bugparallelComplexHeatmapfutureComponent: RNAseqShinyApp – Heatmap Rendering Module
🧾 Summary
When executing
make_heatmap_mae()insidefuture_promise()(withmultisessionplan), several warnings and messages are triggered at runtime:🔍 Full warning message
🧭 Root Cause Analysis
use_raster,magick, color scale noticesdevices differdraw()is called insidefuture_promise()→ opens graphics device in workerUNRELIABLE VALUE🧪 Current Behavior
future_promise({ make_heatmap_mae(mae, geneListVec) # internally calls draw() on.exit(dev.off()) # may or may not close the right device }, seed = TRUE) %...>% (function(ht) { if (!is.null(ht)) { makeInteractiveComplexHeatmap(input, output, session, ht, "ht") } else { output$ht_heatmap <- renderPlot({ grid::grid.text("No data available.") }) } })✅ Recommended Fix
make_heatmap_mae()to add adraw_ht = FALSEparameterdraw_ht = FALSE, only build and return theHeatmapobject without callingdraw()future_promise(), only construct the heatmap objectfuture_promise({ make_heatmap_mae(mae, geneListVec, draw_ht = FALSE) }, seed = TRUE) %...>% (function(ht) { makeInteractiveComplexHeatmap( input, output, session, ComplexHeatmap::draw(ht, merge_legend = TRUE), heatmap_id = "ht" ) })✅ Acceptance Criteria
"MultisessionFuture modified devices"warning in logs"UNRELIABLE VALUE: … random numbers"warning appearshtobject is returned correctly to UI🧩 Notes
draw()) opens graphics devices outside the main R session, which is unsafe.seed = TRUEto ensure reproducibility.draw()-freeHeatmapobject significantly reduces serialization size and improves performance.renderImage().