@@ -60,13 +60,33 @@ type VecRemoteConfigCapabilities = libdd_common_ffi::Vec<RemoteConfigCapabilitie
6060pub static mut DDTRACE_REMOTE_CONFIG_CAPABILITIES : VecRemoteConfigCapabilities =
6161 libdd_common_ffi:: Vec :: new ( ) ;
6262
63+ struct ActiveDynamicConfig {
64+ priority : u8 ,
65+ configs : Vec < Configs > ,
66+ }
67+
6368#[ derive( Default ) ]
6469struct DynamicConfig {
65- active_config_path : Option < String > ,
66- configs : Vec < Configs > ,
70+ active_configs : HashMap < String , ActiveDynamicConfig > ,
71+ merged_configs : Vec < Configs > ,
6772 old_config_values : HashMap < String , Option < OwnedZendString > > ,
6873}
6974
75+ fn compute_merged_configs ( active_configs : & HashMap < String , ActiveDynamicConfig > ) -> Vec < Configs > {
76+ let mut sorted: Vec < _ > = active_configs. values ( ) . collect ( ) ;
77+ sorted. sort_by_key ( |c| c. priority ) ;
78+ let mut seen = HashSet :: new ( ) ;
79+ let mut merged = vec ! [ ] ;
80+ for entry in sorted {
81+ for config in & entry. configs {
82+ if seen. insert ( mem:: discriminant ( config) ) {
83+ merged. push ( config. clone ( ) ) ;
84+ }
85+ }
86+ }
87+ merged
88+ }
89+
7090pub struct RemoteConfigState {
7191 manager : RemoteConfigManager ,
7292 live_debugger : LiveDebuggerState ,
@@ -109,6 +129,7 @@ pub unsafe extern "C" fn ddog_init_remote_config(
109129 DDTRACE_REMOTE_CONFIG_CAPABILITIES . push ( RemoteConfigCapabilities :: ApmTracingLogsInjection ) ;
110130 DDTRACE_REMOTE_CONFIG_CAPABILITIES . push ( RemoteConfigCapabilities :: ApmTracingSampleRate ) ;
111131 DDTRACE_REMOTE_CONFIG_CAPABILITIES . push ( RemoteConfigCapabilities :: ApmTracingSampleRules ) ;
132+ DDTRACE_REMOTE_CONFIG_CAPABILITIES . push ( RemoteConfigCapabilities :: ApmTracingMulticonfig ) ;
112133
113134 DDTRACE_REMOTE_CONFIG_PRODUCTS . push ( RemoteConfigProduct :: AsmFeatures ) ;
114135 DDTRACE_REMOTE_CONFIG_CAPABILITIES . push ( RemoteConfigCapabilities :: AsmAutoUserInstrumMode ) ;
@@ -254,8 +275,8 @@ fn remove_old_configs(remote_config: &mut RemoteConfigState) {
254275 for ( name, val) in remote_config. dynamic_config . old_config_values . drain ( ) {
255276 reset_old_config ( name. as_str ( ) , val) ;
256277 }
257- remote_config. dynamic_config . old_config_values . clear ( ) ;
258- remote_config. dynamic_config . active_config_path = None ;
278+ remote_config. dynamic_config . active_configs . clear ( ) ;
279+ remote_config. dynamic_config . merged_configs . clear ( ) ;
259280}
260281
261282fn insert_new_configs (
@@ -338,14 +359,17 @@ pub extern "C" fn ddog_process_remote_configs(remote_config: &mut RemoteConfigSt
338359 apply_config ( rc_ref, debugger, limiter) ;
339360 }
340361 RemoteConfigData :: DynamicConfig ( config_data) => {
362+ let priority = config_data. priority ( ) ;
341363 let configs: Vec < Configs > = config_data. lib_config . into ( ) ;
342364 if !configs. is_empty ( ) {
365+ remote_config. dynamic_config . active_configs
366+ . insert ( value. config_id , ActiveDynamicConfig { priority, configs } ) ;
367+ let merged = compute_merged_configs ( & remote_config. dynamic_config . active_configs ) ;
343368 insert_new_configs (
344369 & mut remote_config. dynamic_config . old_config_values ,
345- & mut remote_config. dynamic_config . configs ,
346- configs ,
370+ & mut remote_config. dynamic_config . merged_configs ,
371+ merged ,
347372 ) ;
348- remote_config. dynamic_config . active_config_path = Some ( value. config_id ) ;
349373 }
350374 }
351375 RemoteConfigData :: Ignored ( _) => ( ) ,
@@ -360,8 +384,17 @@ pub extern "C" fn ddog_process_remote_configs(remote_config: &mut RemoteConfigSt
360384 }
361385 }
362386 RemoteConfigProduct :: ApmTracing => {
363- if Some ( path. config_id ) == remote_config. dynamic_config . active_config_path {
364- remove_old_configs ( remote_config) ;
387+ if remote_config. dynamic_config . active_configs . remove ( & path. config_id ) . is_some ( ) {
388+ if remote_config. dynamic_config . active_configs . is_empty ( ) {
389+ remove_old_configs ( remote_config) ;
390+ } else {
391+ let merged = compute_merged_configs ( & remote_config. dynamic_config . active_configs ) ;
392+ insert_new_configs (
393+ & mut remote_config. dynamic_config . old_config_values ,
394+ & mut remote_config. dynamic_config . merged_configs ,
395+ merged,
396+ ) ;
397+ }
365398 }
366399 }
367400 _ => ( ) ,
@@ -529,7 +562,7 @@ pub unsafe extern "C" fn ddog_remote_config_alter_dynamic_config(
529562 {
530563 let mut ret = false ;
531564 let config_name = config. to_utf8_lossy ( ) ;
532- for config in remote_config. dynamic_config . configs . iter ( ) {
565+ for config in remote_config. dynamic_config . merged_configs . iter ( ) {
533566 let name = map_config_name ( config) ;
534567 if name == config_name. as_ref ( ) {
535568 let val = map_config_value ( config) ;
@@ -559,6 +592,8 @@ pub unsafe extern "C" fn ddog_setup_remote_config(
559592pub extern "C" fn ddog_rshutdown_remote_config ( remote_config : & mut RemoteConfigState ) {
560593 remote_config. live_debugger . spans_map . clear ( ) ;
561594 remote_config. dynamic_config . old_config_values . clear ( ) ;
595+ remote_config. dynamic_config . active_configs . clear ( ) ;
596+ remote_config. dynamic_config . merged_configs . clear ( ) ;
562597 remote_config. manager . unload_configs ( & [
563598 RemoteConfigProduct :: ApmTracing ,
564599 RemoteConfigProduct :: LiveDebugger ,
0 commit comments