Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Possible bug: DataBoundComponent.dbcDataSourceDataChanged oddity

    Hi,

    We had an odd problem in our app when making data synchronization via updateCaches calls. While updating some not-related DataSource records some of our forms did not-needed redraws which cause problems with some of our custom widgets.

    We noticed an oddity in DataBoundComponent code:

    Code:
        ...
        // internal observation of ds.dataChanged, which is used to provide cache // sync for DBCs with a DS but no RS
        this.observe(ds, "dataChanged", "observer.dbcDataSourceDataChanged(observed,dsRequest,dsResponse)");
        ...
    
        dbcDataSourceDataChanged : function (dataSource, dsResponse, dsRequest) {
            ...
        }
    It seems that dsResponse and dsRequest parameters are in wrong order in observe method. As we did our data synchronization with updateCaches(dsResponse) - without providing the dsRequest - the code in place failed to match the primary key values and thus, invoked setValues for all forms bound to this DS.

    We fixed the problem in our code by calling updateCaches(dsResponse, dsRequest) variant but as we found it to be a quite low-level bug (if it is a bug?), we saw it necessary to report it to you.

    Using v13.0p_2022-08-27/LGPL Development Only (built 2022-08-27).

    #2
    Forms are designed to refresh themselves if the record they are editing is changed. This is so that in a complex multi-screen application, you don't get stale data if you return to a tab you haven't used in a while. If we did not do this, you'd either have the risk of users trying to save stale data, or you'd have to have forms re-fetch data if they were shown again after not fetching for a while, so this is by design.

    This data refresh would only happen if the form was editing the specific record that was updated. So the PK (primaryKey) value in the form would have to match the primaryKey found in the data, which wouldn't happen even if the dsRequest and dsResponse were reversed. So we can't see anyway that even with reversed parameters, you could be seeing all forms refreshing.

    Finally, setValues() does not cause a redraw by default - perhaps you are forcing one?

    Comment


      #3
      Hi,

      Yes, we understand the logic. And yes, the problem is our own custom components that we redraw but now we need dirty workarounds to avoid this.

      But the issue (for our eye at least) seems to be that we think the primary key check is broken because the dsRequest and dsResponse parameters are passed in the wrong order. I suggest you at least check if the observe(...) function you pass has the correct signature.

      Comment


        #4
        We have already checked it, found it was reversed, and fixed it. Thanks for pointing that out!

        However, the thing is, even with reversed parameters, the functionality passes all manual and automated tests that could be applied. This is because, when you are doing an update, and it succeeds, you would expect the dsRequest data and the dsResponse data to be the same, because the update succeeded, so now the data should match, right?

        So while, we've correct the order, so far, we cannot find an actual bug here.

        In particular, in your case, no extra forms should have been updated, because the matching is still done by PK.

        So, in your application, something else must also be wrong. We are looking at the logic and we have a few speculations:

        1. maybe you have no primaryKey declared in any involved DataSource (not valid for an update)

        2. maybe you do have primaryKeys, and your server logic works in terms of those primaryKeys, but you never declared them for the framework (which isn't valid and would cause unspecified behavior)

        3. variation of 2: maybe you have a hack where you declare PKs for SmartClient to try to get around the requirement for them, but then they are always null or always the same value, and this has miraculously worked for your current usage, except this

        Does this make sense with what you are seeing?

        Also, as far as a "dirty workaround", we think you mean that you implemented a workaround regarding "dirtyness" so that extra redraws were avoided. But, to be clear, that would be a performance benefit only - any behavior that depended on the timing or number of redraws would be an unsupported approach, subject to breakage at any time. Drawing and redrawing is intended to be entirely separate from other behaviors such as management of the current value, so it would not be valid to intertwine the two aspects.

        If your custom component does depend on the number of redraws of the redraw timing in some way, please feel free to ask about how it could be changed to not rely on redraws or redraw timing (separate thread would be better). If the result of the discussion is that new APIs or new docs are required to do this for your scenario, we will definitely look at adding that.

        Comment


          #5
          Thanks!

          In this case, we have situations in our app where we need to update the caches manually - without making an actual request. We have some connection channels where we detect changes in some data. To update this, we did

          Code:
              DSResponse r = new DSResponse();
              r.setDataSource(ourDS);
              r.setData(ourChangedRecord);
              r.setOperationType(DSOperationType.UPDATE);   
              ourDS.updateCaches(r);
          By looking this with a debugger, it seems that the dsRequest in dbcDataSourceDataChanged function has no data attribute and thus, fails.

          By changing the above to

          Code:
              DSResponse r = new DSResponse();
              r.setDataSource(ourDS);
              r.setData(ourChangedRecord);
              r.setOperationType(DSOperationType.UPDATE);
              ourDS.updateCaches(r, new DSRequest(DSOperationType.UPDATE, ourChangedRecord));
          .. works.

          Comment

          Working...
          X