Announcement

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

    problem with automatic cache synchronization and queueing

    SmartClient Version: v13.1p_2025-02-24/Enterprise Development Only (built 2025-02-24)

    Hello, I think that I've found a bug in automatic cache synchronization when using queueing.
    Please modify the fetchOperationFS sample like this:

    Code:
    <DataSource isSampleDS="true"
        ID="supplyItem"
        serverType="sql"
        tableName="supplyItem"
        titleField="itemName"
        testFileName="/examples/shared/ds/test_data/supplyItem.data.xml"
        dbImportFileName="/examples/shared/ds/test_data/supplyItemLarge.data.xml"
    >
    
        <fields>
            <field name="itemID" type="sequence" hidden="true" primaryKey="true"/>
            <field name="itemName" type="text" title="Item" length="128" required="true"/>
            <field name="SKU" type="text" title="SKU" length="10" required="true"/>
            <field name="description" type="text" title="Description" length="2000"/>
            <field name="category" type="text" title="Category" length="128" required="true"
                   foreignKey="supplyCategory.categoryName"/>
            <field name="units" type="enum" title="Units" length="5">
                <valueMap>
                    <value>Roll</value>
                    <value>Ea</value>
                    <value>Pkt</value>
                    <value>Set</value>
                    <value>Tube</value>
                    <value>Pad</value>
                    <value>Ream</value>
                    <value>Tin</value>
                    <value>Bag</value>
                    <value>Ctn</value>
                    <value>Box</value>
                </valueMap>
            </field>
            <field name="unitCost" type="float" title="Unit Cost" required="true">
                <validators>
                    <validator type="floatRange" min="0" errorMessage="Please enter a valid (positive) cost"/>
                    <validator type="floatPrecision" precision="2" errorMessage="The maximum allowed precision is 2"/>
                </validators>
            </field>
            <field name="inStock" type="boolean" title="In Stock"/>
            <field name="nextShipment" type="date" title="Next Shipment"/>
        </fields>
    
        <operationBindings>
            <operationBinding operationId="firstFetch" operationType="fetch" />
        </operationBindings>
        <operationBindings>
            <operationBinding operationId="firstUpdate" operationType="update" />
        </operationBindings>
        <operationBindings>
            <operationBinding operationId="secondFetch" operationType="fetch" outputs="itemName, itemID" />
        </operationBindings>
        <operationBindings>
            <operationBinding operationId="secondUpdate" operationType="update" cacheSyncOperation="secondFetch" />
        </operationBindings>
    
    </DataSource>
    Code:
    isc.ListGrid.create({
        ID: "dsListGrid",
        top: 40,
        width: "100%",
        height: "100%",
        autoFetchData: true,
        dataSource: "supplyItem",
        fetchOperation: "firstFetch",
        updateOperation: "firstUpdate",
        canEdit: true
    });
    
    isc.IButton.create({
        ID: "customUpdate",
        title: "Custom Update",
        click: function () {
            isc.RPCManager.startQueue();
            dsListGrid.refreshData();
            var record = dsListGrid.getSelectedRecord()
            supplyItem.updateData({itemID: record.itemID, nextShipment: new Date()}, null, {operationId: "secondUpdate"})
            isc.RPCManager.sendQueue(function (responses) {
            });
        }
    })

    Then, select a record and click the "Custom Update" button. This will create a queue, where the 2nd request is an update with an operationId and a cacheSyncOperation. Both operationIds are different from the grid's fetchOperation and the updateOperation. Nevertheless it seems that the framework is using the returned record to update the client cache.

    #2
    I actually noticed this problem because I've got a formatCellValue, and it is called also for the "secondUpdate" cache sync.

    Now I'm trying a workaround without queue, but my formatCellValue is still called for the secondUpdate, so it seems not actually related to the queue.

    If you try this modified test case:

    Code:
    isc.ListGrid.create({
        ID: "dsListGrid",
        top: 40,
        width: "100%",
        height: "100%",
        dataSource: "supplyItem",
        fetchOperation: "firstFetch",
        updateOperation: "firstUpdate",
        canEdit: true,
        fields: [
            {name: "itemName"}, {
                name: "SKU",
                formatCellValue: function (value, record, rowNum, colNum, grid) {
                    debugger;
                    isc.logEcho(record);
                    return value;
                }
            }
        ]
    }).fetchData({itemID: 1});
    
    isc.IButton.create({
        ID: "customUpdate",
        title: "Custom Update",
        enableWhen: {fieldName: "dsListGrid.numSelected", operator: "equals", value: 1},
        click: function () {
            var callback = function (dsResponse, data, dsRequest) {
                var record = dsListGrid.getSelectedRecord()
                debugger;
                supplyItem.updateData({
                    itemID: record.itemID,
                    nextShipment: new Date()
                }, null, {operationId: "secondUpdate"})
            }
            dsListGrid.refreshData(callback);
        }
    })
    you may see that formatCellValue is called also after the "secondUpdate".

    Comment


      #3
      Hello, may I ask if you see the problem, or if I'm missing something?

      Comment


        #4
        Hi Claudio
        Sorry for the delay on this one - it's sparked some internal discussion and analysis.

        The issue here is basically an inaccuracy in the ResultSet documentation. The documentation for ResultSet claims that cache synchronization in response to add or update operations will not occur when the ResultSet's fetch operation doesn't match the add/update's "cacheSynchOperation".
        That's inaccurate - the ResultSet will integrate changes into its cache even if its fetch doesn't match up with the cacheSynchOperation for an add or update operation on the same DataSource.

        We will be correcting the documentation, and our design team is considering whether/how to also add an attribute to enable strict cache enforcement support.

        We will follow up on this thread with updates as they occur.

        One question for you: Is this causing issues in your application design currently / do you have a workaround?
        If this is causing you difficulty, please also let us know your use case so we can make sure it is fully considered as we improve this area.

        Thanks and Regards
        Isomorphic Software

        Comment


          #5
          Hello, I believe I originally learned that cache synchronization depended on the operationId thanks to this thread, where Blama also participated:
          https://forums.smartclient.com/forum...d-notification

          I'm also quite sure that at some point over the years, I had to apply workarounds in my code to "bypass" this behaviour. So now, it seems to me that the behaviour has changed.
          My first concern is that there might be parts of my applications that need to be reviewed, and at the moment, I wouldn't know how to easily identify them.

          Regarding my specific case: I have a grid whose DataSource has a custom update operation that modifies a field that is not visible in the grid. Its cacheSyncOperation is a query that retrieves a summary (which changes after the update), and this is the actual data that I need to visually update, however, the framework is trying to use the result to update the grid.

          With the current behaviour, would I be forced to use a separate DataSource for this operation?

          Comment


            #6
            You’re correct - we had a rare flub in that thread, where documentation was added to describe existing behavior, but the existing behavior was not actually what we thought.

            As far as the actual behavior, our analysis shows that it actually never changed - only the documentation changed.

            We’re hoping that this means that you adjusted your code *anticipating* the framework behavior we described, rather than that the behavior actual changed. But please let us know if you’re seeing a behavior change.

            Comment

            Working...
            X