Posted by xjm

Problem/Motivation

Default configuration entities provided by a module will typically have object names in the format:

namespace.other_prefixes.type.machine_name

E.g., views.view.frontpage or block.block.bartik.tools

However, regardless of the config prefix, the entity system requires the machine name to be unique for a given entity type, so default configuration provided by a module will not be installed properly when two modules provide an entity with the same machine name. With #1887654: Creating a config entity with an existing machine name shouldn't work, the second object installed silently overwrites the first. Once that issue is fixed, installing the second module will presumably throw an exception.

Attached test (for #1887654: Creating a config entity with an existing machine name shouldn't work) demonstrates this.

Proposed resolution

  1. Recommend a best practice of prefixing default configuration entity IDs with the module name, e.g.: views.view.node_frontpage, block.block.bartik.user_online, etc.
  2. Update default configuration entities already in core (views, blocks, etc.) to this convention.

Remaining tasks

I'll roll the patch once we're agreed. The patch is postponed on #1871696: Convert block instances to configuration entities to resolve architectural issues since a lot of the offenders are in the Block module.

Related issues

CommentFileSizeAuthor
1887654-config-import-test.patch2.09 KBxjm
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

xjm’s picture

Status: Needs review » Postponed
Issue tags: +Configuration system, +VDC, +Blocks-Layouts, +Configurables
xjm’s picture

Issue tags: +Block plugins
xjm’s picture

Issue summary: View changes

Updated issue summary.

sun’s picture

The module name prefix must be delimited with a dot/period, in order to prevent nameclashes:

node.type.foo_bar_baz == node.type.foo_bar_baz

node.type.foo.bar_baz != node.type.foo_bar.baz
xjm’s picture

But then wouldn't we end up back in the situation? The entity system has no way to differentiate whether it came from the foo.bar.module1 namespace or the foo.bar.module2 namespace. It has to be something that's included in the machine name to prevent collisions. I don't see the scenario in #3 arising under non-contrived circumstances, because a given entity type is not going to have an object name with a variable number of pieces.

I guess the alternative would be to hardcode that configuration entities always have a two-part machine name, but it would have to be baked into the storage controller, and adding the "owner" module as a required part of the name alongside the "API" module has been rejected several times. Edit: That also would mean that, even capping the module and machine name length at 64 characters, the machine name would take up more than half of the potential allowed characters for the object name. With the API module as the first segment, there's less than 64 characters remaining for the rest of the namespace. The difference between hardcoding this and recommending it as a best practice is that core modules do not have 64-character names.

Edit: It would make solving #1871772: Convert custom blocks to content entities easier for entities, but it wouldn't resolve that problem for non-entities. Actually it wouldn't, because we have no way to select on the second-to-last component of a configuration object name, and no guarantee of what the second-to-last component of an object name might contain for non-configuration entities.

sun’s picture

All that #3 really changes vs. #0 is that #0 doesn't account for conflicting [module]_[id] combinations, because it is using underscores to delimit the module name from the ID.

The problem space is essentially the same we have with module hook function names already — since the module and hook is separated by a single underscore only, and since both module names as well as hook names are compound of underscores, there is factually no uniqueness in possible module + hook combinations. Uniqueness would only be guaranteed if module + hook were delimited by a double underscore (e.g., hook__menu()). That's a critical architectural bug, which is open since like forever (~2005).

Thus, uniqueness in config object names can only be ensured if the module part is cleanly separated from the ID part.

The only change to #0 is that one critical underscore is exchanged with a dot/period.

That's required to make sense of this proposal. Otherwise, the prefix wouldn't result in uniqueness, and the effective result would be equal to not having/enforcing this naming at all.

xjm’s picture

Status: Postponed » Active
xjm’s picture

Issue summary: View changes

Updated issue summary.

xjm’s picture

Assigned: xjm » Unassigned

:)

xjm’s picture

Issue summary: View changes

Removing myself from the author field so that I can unfollow the issue. --xjm

xjm’s picture

Issue tags: +Naming things is hard
xjm’s picture

Status: Active » Closed (duplicate)
xjm’s picture