@@ -92,6 +92,7 @@ Dash <- R6::R6Class(
92
92
private $ suppress_callback_exceptions <- suppress_callback_exceptions
93
93
private $ compress <- compress
94
94
private $ app_root_path <- getAppPath()
95
+ private $ timing_information <- list ()
95
96
private $ app_launchtime <- as.integer(Sys.time())
96
97
private $ meta_tags <- meta_tags
97
98
private $ in_viewer <- FALSE
@@ -844,18 +845,21 @@ Dash <- R6::R6Class(
844
845
# ' @param description Character. A description of the resource.
845
846
# '
846
847
callback_context.record_timing = function (name ,
847
- duration = NULL ,
848
+ duration = NULL ,
848
849
description = NULL ) {
849
- timing_information <- self $ server $ get_data( " timing-information " )
850
+ timing_information_ <- attributes(dynGet( " request " )) $ timing_information
850
851
851
- if (name %in% timing_information ) {
852
+ if (name %in% timing_information_ ) {
852
853
stop(paste0(" Duplicate resource name " , name , " found." ), call. = FALSE )
853
854
}
854
855
855
- timing_information [[name ]] <- list (" dur" = round(duration * 1000 ),
856
- " desc" = description )
856
+ timing_information_ [[name ]] <- list (" dur" = round(duration * 1000 ),
857
+ " desc" = description )
857
858
858
- self $ server $ set_data(" timing-information" , timing_information )
859
+ self $ server $ set_data(" timing-information" , timing_information_ )
860
+
861
+ evalq(attr(req , " timing_information" ) <- app $ server $ get_data(" timing-information" ),
862
+ envir = countEnclosingFrames(" request" ))
859
863
},
860
864
861
865
# ------------------------------------------------------------------------
@@ -1246,37 +1250,43 @@ Dash <- R6::R6Class(
1246
1250
self $ config $ props_check <- dev_tools_props_check
1247
1251
1248
1252
if (private $ debug && self $ config $ ui ) {
1249
- self $ server $ on(' before-request' , function (server , ... ) {
1250
- self $ server $ set_data( " timing_information" , list (
1253
+ self $ server $ on(' before-request' , function (server , request , ... ) {
1254
+ attr( request , " timing_information" ) <- list (
1251
1255
" __dash_server" = list (
1252
1256
" dur" = as.numeric(Sys.time()),
1253
1257
" desc" = NULL
1254
1258
)
1255
- ))
1259
+ )
1256
1260
})
1257
1261
1258
1262
self $ server $ on(' request' , function (server , request , ... ) {
1259
- timing_information <- self $ server $ get_data( ' timing-information ' )
1260
- dash_total <- timing_information [[' __dash_server' ]]
1261
- dash_total [[' dur' ]] <- round(as.numeric(Sys.time() - dash_total [[' dur' ]]) * 1000 )
1262
-
1263
+ timing_information_ <- attr( request , " timing_information " )
1264
+ dash_total <- timing_information_ [[' __dash_server' ]]
1265
+ dash_total [[' dur' ]] <- round(( as.numeric(Sys.time() ) - dash_total [[' dur' ]]) * 1000 )
1266
+
1263
1267
request $ response $ append_header(' Server-Timing' ,
1264
1268
paste0(' dash_total;dur=' , dash_total [[' dur' ]]))
1265
1269
1266
- for (item in seq_along(timing_information )) {
1267
- header_content <- paste0(names(timing_information [item ]), ' ;' )
1270
+ # ensure dash_server is not returned within the header
1271
+ timing_information_ <- timing_information_ [names(timing_information_ ) != " __dash_server" ]
1272
+
1273
+ for (item in seq_along(timing_information_ )) {
1274
+ header_content <- paste0(names(timing_information_ [item ]), ' ;' )
1268
1275
1269
- if (! is.null(timing_information [[item ]]$ desc )) {
1270
- header_content <- paste0(header_content , ' desc="' , timing_information [[item ]]$ desc , ' "' )
1276
+ if (! is.null(timing_information_ [[item ]]$ desc )) {
1277
+ header_content <- paste0(header_content , ' desc="' , timing_information_ [[item ]]$ desc , ' "' )
1271
1278
}
1272
1279
1273
- if (! is.null(timing_information [[item ]]$ dur )) {
1274
- header_content <- paste0(header_content , ' ;dur=' , timing_information [[item ]]$ dur )
1280
+ if (! is.null(timing_information_ [[item ]]$ dur )) {
1281
+ header_content <- paste0(header_content , ' ;dur=' , timing_information_ [[item ]]$ dur )
1275
1282
}
1276
1283
1277
1284
request $ response $ append_header(' Server-Timing' ,
1278
1285
header_content )
1279
1286
}
1287
+
1288
+ # flush the context (probably unnecessary, but to be overly safe)
1289
+ attr(request , " timing_information" ) <- list ()
1280
1290
})
1281
1291
}
1282
1292
@@ -1386,16 +1396,13 @@ Dash <- R6::R6Class(
1386
1396
1387
1397
# reset the timestamp so we're able to determine when the last cycle end occurred
1388
1398
private $ last_cycle <- as.integer(Sys.time())
1389
-
1390
- # flush the context to prepare for the next request cycle
1391
- self $ server $ set_data(" timing_information" , list ())
1392
1399
})
1393
1400
} else if (hot_reload == TRUE & is.null(source_dir )) {
1394
1401
message(" \U {26A0} No source directory information available; hot reloading has been disabled.\n Please ensure that you are loading your Dash for R application using source().\n " )
1395
1402
} else if (hot_reload == FALSE && private $ debug && self $ config $ ui ) {
1396
1403
self $ server $ on(" cycle-end" , function (server , ... ) {
1397
- # flush the context to prepare for the next request cycle
1398
- self $ server $ set_data(" timing_information " , list ())
1404
+ # ensure the timing-information store is flushed
1405
+ self $ server $ set_data(" timing-information " , list ())
1399
1406
})
1400
1407
}
1401
1408
@@ -1430,6 +1437,9 @@ Dash <- R6::R6Class(
1430
1437
# callback context
1431
1438
callback_context_ = NULL ,
1432
1439
1440
+ # timing information temporary store
1441
+ timing_information = NULL ,
1442
+
1433
1443
# fields for setting modification times and paths to track state
1434
1444
asset_modtime = NULL ,
1435
1445
app_launchtime = NULL ,
0 commit comments