New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: config package #2439
refactor: config package #2439
Conversation
Codecov ReportBase: 38.57% // Head: 39.48% // Increases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## master #2439 +/- ##
==========================================
+ Coverage 38.57% 39.48% +0.90%
==========================================
Files 168 172 +4
Lines 36728 36619 -109
==========================================
+ Hits 14168 14458 +290
+ Misses 21649 21240 -409
- Partials 911 921 +10
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
022b7b3
to
9d7e1ae
Compare
54681fe
to
e99a83a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1st round 👍
config/config.go
Outdated
c.envLock.RLock() | ||
if _, ok := c.envs[key]; !ok { | ||
c.envLock.RUnlock() | ||
c.envLock.Lock() // don't really care about race here, setting the same value | ||
c.envs[strings.ToUpper(key)] = envVar | ||
c.envLock.Unlock() | ||
} else { | ||
c.envLock.RUnlock() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[optional] Even though you don't care about the race it can make sense to simplify this bit and just Lock()
and defer Unlock()
instead of mixing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For a strange reason I tend to prefer this kind of (biased) optimisation, considering that in most cases the key will be already in the map, so we don't really need to be pessimistic and block competing config readers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I understand, I'm suggesting mostly to simplify the logic. I don't see that much of a performance impact in this case so perhaps simplyfing can be good. Up to you of course 👍
e99a83a
to
5f663d2
Compare
defer func() { | ||
if r := recover(); r != nil { | ||
err := fmt.Errorf("cannot update Config Variables: %v", r) | ||
fmt.Println(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How are we going to catch this when it happens?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Used this piece in its original form, just moved it to another file.
I wouldn't worry that much about it though, since config files don't change randomly in our managed environments. We do changes purposefully and then monitor, expecting to verify that our changes have actually been applied. Failure to do so, might trigger someone to have a look at the logs :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense at least for now it shouldn't cause major issues given that we apply and check 👍
I wonder what we could do to improve these bits, perhaps structured logging might be useful in these cases cc @lvrach
5f663d2
to
f55e59f
Compare
config/load.go
Outdated
_ = c.checkAndHotReloadConfig(c.hotReloadableConfig) | ||
isChanged := c.checkAndHotReloadConfig(c.nonHotReloadableConfig) | ||
if isChanged && getEnvAsBool("RESTART_ON_CONFIG_CHANGE", false) { | ||
os.Exit(1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chandumlg @cisse21 do we really still need this functionality?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can get rid of it... we never actually used this and should be easy to add again if needed
41219b7
to
055edf9
Compare
@@ -98,48 +103,46 @@ func TestEventOrderGuarantee(t *testing.T) { | |||
"workspaceId": workspaceID, | |||
} | |||
configJsonPath := workspaceConfig.CreateTempFile(t, "testdata/eventOrderTestTemplate.json", templateCtx) | |||
t.Setenv("RSERVER_BACKEND_CONFIG_CONFIG_FROM_FILE", "true") | |||
t.Setenv("RSERVER_BACKEND_CONFIG_CONFIG_JSONPATH", configJsonPath) | |||
config.Set("BackendConfig.configFromFile", true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is the reason we are not using t.Setenv
anymore ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We cannot consider having tests running in parallel at any point in the future if we continue using environment variables for setting up our test environments. t.Setenv
sets an environment variable and unsets it when the test is done, but this doesn't mean that the environment variable is specific for the test, it will affect all other tests running in parallel at the same time.
055edf9
to
fc5b2dd
Compare
@@ -258,7 +257,7 @@ func CheckAndValidateWorkspaceToken() { | |||
|
|||
pkgLogger.Warn("Previous workspace token is not same as the current workspace token. Parking current jobsdb aside and creating a new one") | |||
|
|||
dbName := config.GetEnv("JOBS_DB_DB_NAME", "ubuntu") | |||
dbName := config.GetString("DB.name", "ubuntu") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this change backwards compatible ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes see here
@@ -98,48 +103,46 @@ func TestEventOrderGuarantee(t *testing.T) { | |||
"workspaceId": workspaceID, | |||
} | |||
configJsonPath := workspaceConfig.CreateTempFile(t, "testdata/eventOrderTestTemplate.json", templateCtx) | |||
t.Setenv("RSERVER_BACKEND_CONFIG_CONFIG_FROM_FILE", "true") | |||
t.Setenv("RSERVER_BACKEND_CONFIG_CONFIG_JSONPATH", configJsonPath) | |||
config.Set("BackendConfig.configFromFile", true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to understand more behind the motivation of this change?
Given that this is a service integration test that includes the execution of main.go and thus the environment variables parsing are consider part of the application interface.
I assume that the problem was config left over from previous tests, but exposing config here is not the ideal approach. I would like to examine/discuss alternate solutions.
We could use @fracasula were the service executed on a separated process.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Starting a service as a separate process comes with disadvantages too. Please see this comment and let me know if you wish me to elaborate further
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@atzoum it sure has disadvantages like harder to debug (setting breakpoints) and code verbosity (setting up the exec, piping output, etc...). have you come across more issues? I'd like to know because in some places it helped me with isolation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Practically its only advantage is isolation, everything else could be considered as a disadvantage, e.g. a non-restrictive list:
- debugging (practically impossible)
- extensibility (unit testing components, i.e. non-programms)
- intuitiveness (a test case executing
go run
causes some people to say WTF) - configuration (expecting that the version of the go binary executing the test is the same as the go binary available in the path)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point about the configuration. About extensibility one thing is to do an integration test with it, one thing a unit test. The latter definitely not recommended 🙂
a4f964e
to
319c0b4
Compare
Description
Refactoring the
config
package and introducing the following features:Notion Ticket
Link
Security