You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add helper to create a sub-registry or return the existing one if present (#313)
When creating a child registry, code often checks if the registry already exists, since creating a duplicate entry will cause a panic. There are two issues with this:
- Most registry creation has extra identical boilerplate to check if a registry exists before creating it
- This boilerplate is not concurrency-safe, because the registry lock is not held continuously; it's possible for two goroutines to both check the same registry name, both observe that it does not exist yet, and both try to create it. This is rare (I don't know of confirmed occurrences) but if it does happen the entire process will panic.
This PR adds a helper that handles both these issues, replacing the usual checks with a one-line call that properly holds the lock between checking for existing registries and creating new ones.
require.Nil(t, root.GetRegistry("a.b.c"), "GetRegistry on empty registry always returns nil")
167
+
168
+
c:=root.GetOrCreateRegistry("a.b.c")
169
+
require.NotNil(t, c, "GetOrCreateRegistry must be successful on an empty registry")
170
+
assert.Equal(t, c, root.GetRegistry("a.b.c"), "GetRegistry after GetOrCreateRegistry should return the same value")
171
+
assert.Equal(t, "root.a.b.c", c.name, "Registries created with GetOrCreateRegistry should contain the parent name followed by the path to the registry")
172
+
173
+
y:=c.GetOrCreateRegistry("z.y")
174
+
require.NotNil(t, y, "GetOrCreateRegistry must be successful on an empty registry")
175
+
assert.Equal(t, y, c.GetOrCreateRegistry("z.y"), "GetOrCreateRegistry on the same input should return the same result")
176
+
assert.Equal(t, c.GetOrCreateRegistry("z.y"), root.GetOrCreateRegistry("a.b.c.z.y"), "GetOrCreateRegistry with equivalent paths from different starting points should return the same result")
177
+
178
+
c.Add("scalar", &Int{}, Full)
179
+
assert.Nil(t, root.GetOrCreateRegistry("a.b.c.scalar.w.x"), "GetOrCreateRegistry should return nil if part of the path is a non-registry type")
0 commit comments