3 ms·
Somewhat related, how are other gophers handling dynamic configuration in their go apps? Such as if the app is tied to consul or vault to get some config value
by candiddevmike 5y ago
Somewhat related, how are other gophers handling dynamic configuration in their go apps? Such as if the app is tied to consul or vault to get some config value. How do you handle the propagation of config changes cleanly, especially if it impacts something "big" like your DB pool? Do you have mutexes everywhere you read from the config pointer you pass around?
I noodled on this a while ago and figured it was easier to just restart the app on config changes than try to change things on the fly =D
- spyspy 5y agoUsually http handlers or a database functions are pointer methods on some larger Service or DB struct type. If the config changes, you'd have a mutex within that struct and a method that safely modifies its state by locking and unlocking the mutex.
- Philip-J-Fry 5y agoI don't use any of them services, but any config that has multiple readers and a single writer (who updates it when it changes) can just be protected by a sync.RWMutex. The easiest thing to do would be to add a RWMutex to your Config struct. Then have public accessor methods which RLock the mutex while retrieving a field value. Then when you want to update the config have something like a `Set(c Config)` method which allows you to overwrite the config stored in pointer. This Locks the RWMutex for writing of course.
- maximente 5y agoviper, which nicely handles env vars, also can watch for config changes: https://github.com/spf13/viper#watching-and-re-reading-config-files https://github.com/spf13/viper#watching-and-re-reading-confi... if you're rotating creds or need to open/close the DB, this will typically just add another select case to your main method, where you also block on e.g. signal catching to cleanly shutdown the app
- snupples 5y agoBe aware that viper isn't thread safe. You'd still have to copy config by value and then put a mutex on that, then handle reads and writes separately. https://github.com/spf13/viper#is-it-safe-to-concurrently-read-and-write-to-a-viper https://github.com/spf13/viper#is-it-safe-to-concurrently-re...
- Thaxll 5y agoWhy would you send pointer and not just a copy of a configuration? Configuration are usually simple things like url, threadpool size, strings etc ... there is no problem passing a copy of that. Edit: not sure why I'm downvoted, I also think that reloading configuration is a bad idea anyway so you should pass immutable config.
- glenjamin 5y ago> I noodled on this a while ago and figured it was easier to just restart the app on config changes than try to change things on the fly =D I think this is generally the best approach, as it also applies some pressure for your application to be able to quickly shutdown and restart without affecting users - which is a desirable property to have for many other reasons too.
- kyrra 5y agoatomic.Value can work pretty well as well, their example docs show how to do it as well: https://golang.org/pkg/sync/atomic/#example_Value_config https://golang.org/pkg/sync/atomic/#example_Value_config DBPool gets a bit more interesting. In Java world you can you providers that give you access to something, which is what middleware tends to do for Go. If you can have your middleware be able to swap the pool config its loading from, that should work just fine. atomic.Value make work here as well.
- jy3 5y agoJust implement methods in your config struct in such a way that they are safe for concurrent access?! Using a mutex for example. Why would you need it to lock mutexes everywhere?