While reviewing #2256257-11: Move token seed in SessionManager in isSessionObsolete() and regenerate() to the MetadataBag I saw this ugly messing of object mocking for an object that clearly didn't need it. While investigating I found it was because of the complicated way we've set up our Settings object.
In this patch we separate the settings storage from the Settings class and create a separate class to handle it. The storage class can then be instantiated on its own and injected into a constructor during testing.
This retains all the read-only aspects of the settings system. The container won't allow it to be over-ridden and the static methods on Settings will behave in the exact same manner and retain the same interface.
Comment | File | Size | Author |
---|---|---|---|
#24 | add_a_settings_storage-2329817-24.patch | 14.38 KB | Manuel Garcia |
| |||
#14 | settings-bag-2329817-14.interdiff.txt | 5.08 KB | neclimdul |
#14 | settings-bag-2329817-14.patch | 25.64 KB | neclimdul |
Comments
Comment #1
neclimdulOh, #2250491: Remove duplicate methods from Settings class is sort of relevant to this issue. We're sort of adding those methods back on a separate class but with a clear purpose.
This is the subtly important line. The previous line changed global state and left an artifact of the empty storage on the global Settings object. The new line just creates an object.
Comment #2
sunMakes sense to me in general. To think through this verbosely:
Since
Settings
are read-only, theoretically it should be safe and should not matter that the services are getting the value object injected.The proposed construct may cause those injected objects to diverge from the object in the singleton. Special attention to serialization scenarios.
Wondering whether we can proactively prevent that somehow? Could we implement
Serializable
and makeSettingsStorage::unserialize()
instantiate itself by callingSettings::getStorage()
?Aside from the above, minor: Not sure whether
SettingsStorage
is the best name; it's not really a storage, but a fancy hashmap / customArrayObject
-alike value object. How aboutSettingsBag
?Comment #3
damiankloip CreditAttribution: damiankloip commentedGenerally I think this looks like a good plan. Gives us a bit more flexibility. We started using Settings:get() directly in code, but this could enable passing it back as param where it makes sense. This can be a follow up though, for sure.
Would be interested to see what sun thinks about this. I know he wanted to do something with the current state of settings.x post :)Couple of nits:
I am fine with that. Not sure if we officially have to use 'Constructs a..' ?
I think we can squeeze an ", or .." on that line too?
Comment #4
damiankloip CreditAttribution: damiankloip commentedSOrry
Comment #6
sunExisting issues regarding the serialization problem space mentioned in #2.
Comment #7
sunSeveral issues also discussed that our ideal end goal should actually be to remove the singleton pattern from
Settings
— at which point theSettings
class itself would turn into the bag / value object.In essence, the idea would be:
Now that I think of it, that approach would actually inject this new
SettingsBag
value object, so this patch here seems to cleanly contribute towards that goal. :-)Comment #8
neclimdulre: #3 I think the serialization issue you linked could probably better address the serialization problem. I think you may have identified something that may have been overlooked there.
re: #4 I think some of those are(or should be) ports of old methods. Issues I've been watching have services taking Settings as a dependency. As discussed in IRC,
Settings::getHashSalt()
is a bit of a thorn in this model. I'll take a look at that documentation when looking at the failure.re: #7 Agreed, this definitely moving toward that goal.
Comment #9
sun@neclimdul: Can you re-roll to address #3 + potentially rename to
SettingsBag
?Looks like this is a quick win.
Comment #10
neclimdulAgreed, sorry for the delay. Busy weekend then got sick. re-roll, rename, and doc changes in the interdiff.
Comment #12
neclimdulFix a file I seem to have missed? Also noticed some documentation I missed on class properties.
I think there are some fixes needed to some phpunit tests still. I'm not sure why testbot isn't seeing the failures though.
Comment #14
neclimdulDon't know why some of these didn't fail in the original patch. Clearly I suspected testbot and was wrong... luck?
Anyways, fixes for tests in interdiff.
Comment #15
znerol CreditAttribution: znerol commentedHow about reusing
Symfony\Component\DependencyInjection\ParameterBag\ParameterBag
and[...]\FrozenParameterBag
?Comment #16
dawehner@znerol
Well, sure that class would fit quite well, but it feels wrong to depend on a DependencyInjection class.
Did we considered to introduce a Bag component which has no dependency at all, and settings would just use it?
Comment #17
neclimdulWe can't anyways. ParameterBagInterface does not have the default parameter we provide on
get
. Removing that would be a longer and involved process that would need additional community discussion.Comment #19
jhedstromPatch no longer applies.
Comment #20
ashishdalviWe will take this issue on Drupal Mumbai code sprint today.
Comment #21
neclimdulIf you guys don't get to it I can easily get one done. Unfortunately since this changes the return type of getInstance() and the type of the settings service there are 2 API breaks and in its current state it can't go into 8.x.
Comment #22
ashishdalviCleaning unwanted tags
Comment #23
catchWe could add a new settings system alongside the old one, both can take from $settings in settings.php. Move usages to the new one and deprecate the old one. Ugly but not impossible in a minor release, so moving back.
Comment #24
Manuel Garcia CreditAttribution: Manuel Garcia as a volunteer and at Appnovation commentedRerolled against 8.3.x, please review =)
Files that had conflicts:
These files no longer use Drupal\Core\Site\Settings; so I've removed the changes that we were doing there:
Files that previous patch was making changes but are now deleted:
Comment #26
hitesh-jain CreditAttribution: hitesh-jain at Acquia commentedComment #28
Manuel Garcia CreditAttribution: Manuel Garcia as a volunteer and at Appnovation commentedHere is the error that the bot found apparently:
Comment #29
Manuel Garcia CreditAttribution: Manuel Garcia as a volunteer and at Appnovation commented