Open
Description
As described at GafferHQ/gaffer#4320 (comment), making RunTimeTyped queries during static initialisation yields incomplete results, and worse, bakes those incomplete results into RunTimeTyped's internal registry, meaning it will return incomplete results for the duration of the process. Affected functions are :
RunTimeTyped::baseTypeIds()
. Because we can't control static initialisation order, the registration for a base class may not have been made at the time a derived class is registered. SobaseTypeIds()
is implemented to populate the registry of bases lazily, the first time it is called for a given type. If called during static initialisation, it may bake an incomplete list of bases.RunTimeTyped::derivedTypeIds()
. This uses the same strategy asbaseTypeIds()
, but is even more broken. A Pythonimport
can add to the list of derived types at any time, so there is no time at which we can bake the complete results into the registry.RunTimeTyped::inheritsFrom()
. This is implemented usingbaseTypeIds()
.
Possible solutions :
- Implement
inheritsFrom()
usingbaseTypeId()
rather thanbaseTypeIds()
, so it doesn't trigger the early baking. This might be sufficient for the Gaffer use case for now. - If
baseTypeIds()
doesn't reach RunTimeTypedTypeId while generating the result, don't store it and instead return a reference to an empty vector. A later call will successfully do the baking after initialisation is complete. - Don't bake/store the results at all. Always do all the work and return a new result instead of a reference into the registry. This is the only option that can truly solve the problem for
derivedTypeIds()
, but it does mean more repeated work/allocation. Looking at the existing uses, I think this is probably acceptable performance-wise, particularly if we also do 1). It would be an ABI break though, returning by value rather than reference.
Thoughts @danieldresser-ie, @andrewkaufman?
Metadata
Metadata
Assignees
Labels
No labels