matrei commented on issue #15840:
URL: https://github.com/apache/grails-core/issues/15840#issuecomment-6031663768

   @weinellucian I could reproduce the empty restore on 7.1.0 with a single app 
as soon as `spring.profiles.active` is set as a JVM system property: the backup 
created with `new PropertySourcesConfig(configMap)` is already empty, and after 
`clear()`/`merge()` the config is `[:]`. Since system properties are shared by 
all apps in the same Tomcat, that is likely what triggers it in your setup. 
#16547 should fix this regression. But I'd also recommend moving away from 
clearing and re-merging `Holders.config` at runtime:
   
   - `clear()` followed by `merge()` is not atomic. The config is backed by a 
plain `LinkedHashMap`, so while the job runs, request threads can see an empty 
or half-merged config.
   - Many values are copied out of the config once at startup (`@Value`, 
`@ConfigurationProperties`, `GrailsConfigurationAware`, plugin bean 
definitions, datasource settings). Those won't pick up reloaded values anyway, 
so only code that calls `config.getProperty(...)` on every use sees the changes.
   - It relies on internal merge semantics, which is how this broke between 6 
and 7.
   
   A small settings service addresses these. Keep the database values in an 
immutable snapshot, swap it in a single assignment, and fall back to the static 
config for anything not stored in the database:
   
   ```groovy
   import grails.core.GrailsApplication
   import grails.gorm.transactions.Transactional
   
   class SettingsService {
   
       GrailsApplication grailsApplication
   
       private volatile Map<String, String> settings = Collections.emptyMap()
   
       String getSetting(String key) {
           settings.containsKey(key) ? settings[key] : 
grailsApplication.config.getProperty(key)
       }
   
       @Transactional(readOnly = true)
       void reload() {
           var loaded = [:] as Map<String, String>
           AppSetting.list().each { loaded[it.name] = it.settingValue }
           settings = Collections.unmodifiableMap(loaded)
       }
   }
   ```
   
   Call `settingsService.reload()` from `BootStrap` and from your cron job, and 
read dynamic values through `settingsService.getSetting(...)` instead of 
`Holders.config`. Readers always see either the old snapshot or the new one, 
never an empty config, and `application.yml`/external config stay untouched, so 
there is nothing to back up and restore.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to