Issue with object member bindings

We've bumped into an issue on 8.1.26 related to bindings on non-persistent members of property objects...

We've seen this in a bunch of situations, some not related to sub-views, but my minimal example below happens to be using one.

The parameter properties to the sub-view look like this:

view_properties

And the binding on the name property looks like this

binding_sample

What we're finding is that if we do a bunch of stuff that triggers too many changes of session.custom properties in quick succession (but specifically doesn't change any part of dbUserInfo), then that sub-view parameter binding pictured above gets bumped to None:

broken_view

Yeah, I know that "a bunch of stuff" is not the best description. I'm trying to narrow that down, but it's apparently random if it does or doesn't occur and I can't nail it down yet.

The confusing part is that if I make the params.feature.name property persistent, then the issue goes away.

The consistent feature of every place we've seen something like this is that it includes a persistent property object with non-persistent members with bindings. Once that setup exists, it seems like some sort of loophole exists that can cause the parent object to be re-created without the sub-member existing, and once in that state it will never come back.

We have a workaround, but we (unfortunately) have quite a few places that use non-persistent bindings on object sub-members since we didn't realize this was an issue for quite a while.

I'm bringing this up on the forum since I have a gut feeling that this is not the intended behavior and wanted to get some attention on it.

EDIT TO AMEND:

I added a transform script on the binding that just does system.util.getLogger("FOO").warn(unicode(value)) and I can see that within a couple seconds after it breaks it does get re-evaluated and is logging the right value, but it doesn't fix the display to the user... :confused:

Oh this is weirder than I thought and still related to bindings on object sub-members, but likely not related to persistence.

In my test case with persistence turned on I was saving it with a "reasonable" persistent value and thinking I couldn't break it. I put in an "unrealistic" persistent value and realized I can get it to "break" to be stuck on that unrealistic value instead of None/null... So, there's still an issue, but now our workaround doesn't work around it.

I'm trying to narrow this down to a simpler test case, but every time I do that my simpler example works. Something in the many layers of complexity on our project is doing this... :frowning:

Unrelated, but consider adding the gap css style prop to this flex container to put a small gap between your components

I'm in my own tiny hell. I'd bring in IA support but that would still require I be able to give them some sort of simpler test case, which I can't do yet.

I focused on figuring out what "bunch of stuff" was triggering the bug and found a path that reproduces the bug 100% of the time and used that to narrow in further. It appears to be triggered by a write of a very large memory tag holding a 1KB+ string in a Python script. :confused:

There are no views or bindings monitoring that memory tag. I can run the same tag writes in other places and nothing goes wrong, but ... in this one code path if I do the tag write then Perspective objects in many, many other places all suddenly break and fall back to default values and their bindings stop working. If I comment out just the system.tag.writeBlocking then everything works fine.

This almost feels like this one tag write is somehow breaking the Jython instance or the binding engine or Perspective module or ... something really fundamental. But ...

I'm not actually expecting any helpful feedback here, just venting...

I have been digging on this for another day. I'm finding clues, but they all seem random.

  1. It happens more often by writing some big tags than others. But it's not size alone. There are some even bigger tags that I have been unable to make it happen on.
  2. I have been able to make it happen on 2 out of 3 Gateways I tested it on. The one that I was not able to reproduce it on was our production system which doesn't have the tags that most often cause the failure. I'm not convinced it wouldn't happen on production if I had the other tags present.
  3. When the failure happens it sometimes affects multiple Perspective sessions (i.e. other users besides the one who triggered it).
  4. If it does affect more than one user's session, each user can individually logout and back in to get a working session, and the other users' sessions will continue in the broken state
  5. If I add logging output on a binding that breaks, I can actually see logged output showing the correct values even after it's broken, but the correct values never show up in the user's web view
  6. Sometimes forcing a browser refresh will fix it, but not always

My programming experience is really getting it's hackles up on this one. It stinks like a buffer or stack overflow, but I shouldn't be able to make that happen in Jython without seeing some sort of exception, which I'm not. And even in the small chance I found an un-caught memory corruption in an underlying Java module, I would expect NPEs or way more random "Bad Things" to go wrong that just a consistent set of objects with bindings falling back to their default values and no longer updating.

I'm suspicious that I've hit a very esoteric but also very profound bug in an Ignition module, but it's hard to prove anything... :confounded:

I'm going to be stewing on this all weekend, and opening an official support ticket on Monday even if I can't get a better test case...

If anybody with a good sense of Igniton's internal architecture has read this far, does my failure mode of multiple user's bindings all going dead/default at the same time sound like a particular module being corrupted or dying? Like, does the Perspective module have a thread pool where each handles multiple users and maybe one thread is getting jammed up or losing it's mapping of bindings to websocket values?