When you delete a binding instance is it supposed to clean up links?

  • Platform information:
    • Hardware: Raspberry PI 4

OS:

Linux openhab 5.4.51-v7l+ #1333 SMP Mon Aug 10 16:51:40 BST 2020 armv7l GNU/Linux

Java Runtime Environment:

openjdk version "11.0.8" 2020-07-14 LTS
OpenJDK Runtime Environment Zulu11.41+75-CA (build 11.0.8+10-LTS)
OpenJDK Client VM Zulu11.41+75-CA (build 11.0.8+10-LTS, mixed mode)

openHAB version:

3.0.0-SNAPSHOT
Build #1949

Issue of the topic: Orphan links left after binding instance deleted

If logs where generated please post these here using code fences:

10:48:28.860 [DEBUG] [e.thing.internal.CommunicationManager] - Received  event '0' for non-existing thing 'jvcProjector:rs3000:97699a42f1', not forwarding it to the handler
10:48:28.862 [DEBUG] [e.thing.internal.CommunicationManager] - Received  event '0' for non-existing thing 'jvcProjector:rs3000:daa6d5d33e', not forwarding it to the handler

When you delete a binding instance is it supposed to clean up links or leave orphans? Because it doesn’t clean up, it leaves dead links.

[10:53:37] root@openhab:/var/lib/openhab# cat jsondb/org.openhab.core.thing.link.ItemChannelLink.json
{
  "JVCRS3000Projector_Power -\u003e jvcProjector:rs3000:daa6d5d33e:lamp": {
    "class": "org.openhab.core.thing.link.ItemChannelLink",
    "value": {
      "channelUID": {
        "segments": [
          "jvcProjector",
          "rs3000",
          "daa6d5d33e",
          "lamp"
        ]
      },
      "configuration": {
        "properties": {}
      },
      "itemName": "JVCRS3000Projector_Power"
    }
  },
  "JVCRS3000Projector_Power -\u003e jvcProjector:rs3000:dd1111c0dd:lamp": {
    "class": "org.openhab.core.thing.link.ItemChannelLink",
    "value": {
      "channelUID": {
        "segments": [
          "jvcProjector",
          "rs3000",
          "dd1111c0dd",
          "lamp"
        ]
      },
      "configuration": {
        "properties": {}
      },
      "itemName": "JVCRS3000Projector_Power"
    }
  },
  "JVCRS3000Projector_Power -\u003e jvcProjector:rs3000:97699a42f1:lamp": {
    "class": "org.openhab.core.thing.link.ItemChannelLink",
    "value": {
      "channelUID": {
        "segments": [
          "jvcProjector",
          "rs3000",
          "97699a42f1",
          "lamp"
        ]
      },
      "configuration": {
        "properties": {}
      },
      "itemName": "JVCRS3000Projector_Power"
    }
  }
}

It keeps accumulating these.

It’s supposed to leave the links so that users don’t have to go in and relink all their Items in the case where a binding is simply being reinstalled for what ever reason.

That does not make sense. Binding channel instances are unique, as you can see here.

jvcProjector:rs3000:daa6d5d33e:lamp
jvcProjector:rs3000:dd1111c0dd:lamp
jvcProjector:rs3000:97699a42f1:lamp

Orphaned links do not reconnect, because the unique binding instance will never ever exist again, as you can see here. This is literally an example of exactly the use case you just described, and it can’t possibly do what you just described.

What’s more, Channels own Items, Items don’t own Channels. The relational model schema isn’t even set up to support that… Things that have been destroyed can’t have children.

They are not always unique. And when you create the Bridge Thing you have the option to change the ID so that the IDs remain not unique when the Thing is recreated. I’ve had to do this many times for example. That random string can be replaced with something meaningful when you first create/discover the Bridge Thing.

Occasionally there will be cases where all the Things for a given binding need to be recreated. If you are careful to make sure the bridge keeps the same Thing ID (i.e. replace that randomly created string with something meaningful) than all the discovered Things will retain their old ID and the links do not need to be changed on the potentially hundreds of Items those Things are linked to.

Deleting the binding does not remove the links and it’s worked that way from the beginning and it was a design decision because of cases like the above.

So you could get hundreds, or even thousands of these by design?

That doesn’t sound like a very good design to me. It’s actually posting messages to topics that don’t exist. The error doesn’t happen until the CommunicationManager receives the message and tries to look up the handler for the recipient. That’s a complete waste of resources which puts unneeded pressure on garbage collection. If you’re actually going to allow something as silly as that, at least don’t subscribe orphan Items in the first place.

But there really should be tools to handle linking in a more graceful way. Absent that, you need instruction to go into org.openhab.core.thing.link.ItemChannelLink.json with a text editor and clean out the garbage that accumulates.

Than you are free to open an issue or even better file a PR. I’ve explained why the links are not automatically removed. If you reject the reasoning and think you have a better solution you are encouraged to make a change to the software.

1 Like

I also agree that they should be removed - in a world where the user is interacting through a UI, having links hang about forever is really bad (IMHO). It’s fine for experienced users who may understand the complexities and intricacies of the inner workings of the system, but not for most normal users (again - IMHO).

I’m not sure if this is the case that @tlum means - I know he says “delete a binding instance”, but I wonder if he really means deleting the thing (I often see the word binding to mean creating a thing - a link between the physical and virtual world).

Clearly we don’t want to remove everything whenever the binding is updated or reinstalled, however IMHO we should be removing links when a thing or item is deleted, and I don’t think that’s the case now - and I think (???) that this is what @tlum might mean?

I’ve already opened an issue on this in ESH a few years back, and it was generally accepted as being a good idea, but not implemented -:

Maybe this issue should be moved to OH-Core…

A CLI command is at least now available to manually remove them -:

When the Item is removed IO absolutely agree, the Link should be removed too. No Item, no need for the link.

I’m still ambivalent about it when removing the Things though. For example, awhile back when we all needed to recreate the all the Zwave Things because of the new Zwave binding updates. Wouldn’t I have to recreate all the Item links again? There’s no way for the system to know that I’m going to immediately recreate/rediscover those Things again. In a sizable system that’s a whole lot of work to go recreate those Links. Even more so if you have to click through the UI (even the new MainUI) to recreate them.

Maybe if there is a checkbox one can click to preserve the links when deleting the Things so that the user has to take positive action to keep the links around instead of creating all that extra work where the Things will be recreated again really soon therefore. By default it will remove the links. That could be a compromise.

As I said before and also in the linked PR: the item is Remonde of you cut it from one file and paste it in another file.

I don‘t think you want to lose all links in that case.

Yes, I guess technically it’s a unique Thing instance. This came up because I found that creating a Thing Instance will make a point-in-time copy of channel-types. So, each time I deploy another version of the binding I’m working on I need to drop and re-instantiate the Thing so that it has a consistent point-in-time snapshot of the channel-type. Then I started to notice the linked Items - which are children of the Channels - weren’t being cleaned up, so were left as orphans. Worse still, they’re still being subscribed to topics on the message bus, so there is resource overhead associated with the orphans.

So, now I’ve learned that I need to make sure I delete the Items before I delete the Thing so I don’t accumulate all the orphan Links.

  • The Links can stay, but they ought to be moved/tagged as obsolete, and not be subscribed to anything.
  • When you instantiate a Thing it ought to check to see if there are any obsolete Links that match the Things ThingTypeUID - without the unique portion - where the ChannelUID signatures match, and offer the user the option to [ALL|SELECTIVELY] reconnect the obsolete Links to the new Thing Instance, or not.
  • There ought to be a UI to clean up the obsolete Links. Right now, as children of the Thing’s Channels, once the Thing is gone the Items and their Links disappear from most views.

Right now I’m kind of tied up working on the Binding I’m trying to create so I don’t have a lot of extra time to start digging into the frameworks core code… and something of this significance should probably go through a Request For Comment stage before someone unilaterally takes it upon themselves to “fix” anything, because I know there are many interested parties.

For this reason I always create my test configurations in file.

Right, that’s another strategy. The killer though is all the time wasted on debugging, only to learn that you need to develop and follow A strategy. What’s most costly for me is the WHAT NOT TO DO learning curve.

1 Like

@chris if Things were deleted when a binding was removed you would not be able to uninstall the Zwave binding to install a snapshot version without rebuilding all your Zwave Things.

This is One reason why I have used textual files for years. I would like to see a feature that can be run Only on demand to Find and delete unlinked / orphaned items.

Often you want them left in place when removing and reading a thing or binding due to it having new config options, so it would be handy to have a manually started clean up feature.

With the new ‘create equipment from thing’ feature the items can be quickly Re created and not have sitemaps and other features break. Worth checking this out if you have not used it yet.

Current behavior is even worse:
When deleting an item that is currently linked, openhab will automatically create a new item that can not be deleted any more and automatically link it accordingly.

How about metadata of an item?
Because currently metadata does not get deleted when you delete an item and without an item you can’t delete the metadata any more.
Checking if an item has metadata before deletion does also not work so inherently you end up with metadata polluting your installation.

Which seems to be a workaround, not a solution :wink:

As I said above - the word “binding” was misused here. Binding is often used (incorrectly) to mean a link to a thing, or something along those lines. Clearly removing the binding itself should not remove all items / things etc. This is what I already said though -:

Fine - but that’s a different issue. The system supports a UI to do all this stuff, and that should work properly. We shouldn’t just say that people need to use text files as the UI doesn’t work.

For me, as I think I said in the original issue, if you delete an item, or a thing, then it’s gone, and all configuration associated with it should probably be removed or it is orphaned.

3 Likes

That would be the behavior anyone would intuitively expect and one thing I really hoped would be tackled with OH3.
E.g.:
Deleting a thing should delete all the channels pointing to it
Deleting an item should delete the channel pointing to it and the metadata associated with it.

Edit:
Also Metadata should be part of an item.

1 Like

There should be a warning message that needs to be acknowledged though.

I think junk metadata is less of a problem because it is ignored. It doesn’t generate errors like the OP points out. Ideally I think the metadata should be deleted. Over all, the REST APIs around metadata need a lot of work IMO to handle stuff like this and management of metadata through the UI. But since it doesn’t really cause any problems beyond a tiny amount of extra entries in the metadata JSONDB file I would treat that as less of a problem.

While looking for something entirely unrelated in the code last night, I discovered that Orphaned Link Management exists in the CLI.

Specifically openhab:links orphan list and openhab:links orphan purge

openhab> help
openhab> openhab:links                                                                                                                                                                                             
Usage: openhab:links list - lists all links
Usage: openhab:links addChannelLink <itemName> <channelUID> - links an item with a channel
Usage: openhab:links removeChannelLink <itemName> <thingUID> - unlinks an item with a channel
Usage: openhab:links clear - removes all managed links
Usage: openhab:links orphan - <list|purge> lists/purges all links with one missing element
openhab> openhab:links orphan --help                                                                                                                                                                               
Specify action 'list' or 'purge' to be executed: orphan <list|purge>
openhab> openhab:links orphan list                                                                                                                                                                                 
Thing channel missing: JVCRS3000Projector_Power -> jvcProjector:rs3000:63d811e9db:lamp
openhab> openhab:links orphan purge
Thing channel missing: JVCRS3000Projector_Power -> jvcProjector:rs3000:63d811e9db:lamp
Link JVCRS3000Projector_Power -> jvcProjector:rs3000:63d811e9db:lampsuccessfully removed.
openhab> openhab:links orphan list
openhab>

So, my 3rd bullet is of lower priority than the other two given it’s at least been addressed already in the CLI… and I’m no longer ignorant of that fact.