Announcement

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

    DSCallback fails while using different DSRequests

    Isomorphic,

    I had a doubt regarding DSCallbacks.

    I have two scenarios.

    In First scenario,
    Im trying to run one data fetch inside DSCallback of another data fetch. Here both are having same DataSource but different DSRequest. This is nested to 3 levels(Here I have shown 2).

    DataSource dataSource = DataSource.get("ds1");
    DSRequest dsRequest = new DSRequest();
    dsRequest.setOperationId("opID1");
    dataSource.fetchData(null, new DSCallback() {
    @Override
    public void execute(DSResponse dsResponse, Object o, DSRequest dsRequest) {
    DSRequest dsRequest2 = new DSRequest();
    dsRequest2.setOperationId("opID2");
    dataSource.fetchData(null, new DSCallback() {
    //Code goes here
    }, dsRequest2);
    //Code goes here
    }
    }, dsRequest);


    In the second scenario im trying to run one data fetch inside DSCallback of another data fetch. Here both are having different DSRequest as well as different DataSource. This is nested to 3 levels(Here I have shown 2).

    DataSource dataSource = DataSource.get("ds1");
    DSRequest dsRequest = new DSRequest();
    dsRequest.setOperationId("opID1");
    dataSource.fetchData(null, new DSCallback() {
    @Override
    public void execute(DSResponse dsResponse, Object o, DSRequest dsRequest) {
    DataSource dataSource2 = DataSource.get("ds2");
    DSRequest dsRequest2 = new DSRequest();
    dsRequest2.setOperationId("opID2");
    dataSource2.fetchData(null, new DSCallback() {
    //Code goes here
    }, dsRequest2);
    //Code goes here
    }
    }, dsRequest);

    What I'm observing here is that the nested data fetches aren't happening syncronously in both the scenarios. Is there anyway I can get them running syncronously?? aren't nested DSCallbacks supposed to run syncronously?

    Vinod

    #2
    This is client side code. So what you're doing here is issuing a fetch request, then when the request returns the callback executes, which in turn issues another fetch request.
    This is necessarily an asynchronous process - all this code runs on the client and is never sent to the server, so there's no way for it to run the callback until the server returns the data each time.

    There are a couple of things you should be aware of with respect to performing multiple operations with a single transaction.

    Firstly you can use queueing (covered in the RPCManager documentation) to bundle multiple, potentially unrelated requests into a single client/server transaction. You simply start a queue, use standard APIs to "send" the DataSource requests (which will actually simply add them to the queue on the client side), then call the sendQueue API to send a transaction containing all the requests. Callbacks will fire for each bundled request when the transaction returns.

    In some cases you may want to perform chained operations, where the result of the first operation will impact the second operation to be performed.
    An example might be to add a new record to one datasource, which creates a new sequence value, then use that newly minted record to update a second datasource. For example, create a user account and create a new order using that new user account in a synchronous chain of operations.
    You can achieve this with some simple server side logic.

    One approach is demonstrated here. In this example, client side code issues two queued requests. The second request has a custom operation binding defined on the dataSource, which causes its values to be populated using values from the response of the previous request.
    Alternatively, you could write custom server code using DMI or similar which explicitly creates and issues multiple dataSource requests on the server-side, allowing you to update multiple tables etc from a single call from the client.

    Comment


      #3
      Isomorphic,

      Thanks for the response.

      Yes, what Im trying to achieve here is a case something exactly similar to the synchronous chain of operations you mentioned. One dsCallback inside another.

      It works fine with a normal single DSCallback inside another single DSCallback.

      But when i introduce a for loop based on the dsresponse of outer data fetch the for loop of DSCallbacks of the fetch inside the loop don't happen syncronously. Please consider the following snippet.


      DataSource dataSource = DataSource.get("ds1");
      DSRequest dsRequest = new DSRequest();
      dsRequest.setOperationId("opID1");
      dataSource.fetchData(null, new DSCallback() {
      @Override
      public void execute(DSResponse dsResponse, Object o, DSRequest dsRequest) {

      for(/* Based on dsresponse of outer fetch */){

      DSRequest dsRequest2 = new DSRequest();
      dsRequest2.setOperationId("opID2");
      dataSource.fetchData(null, new DSCallback() {
      @Override
      public void execute(DSResponse dsResponse, Object o, DSRequest dsRequest) {
      //Code goes here
      }
      }, dsRequest2);

      } // end of for loop
      }
      }, dsRequest);

      Please let me know what im doing wrong in this approach or is there another way to handle this situation?

      Vinod

      Comment


        #4
        This will not be synchronous.

        See the previous advice about Queuing for how multiple request can be submitted together.

        Comment


          #5
          Yeah,

          Since its asynchronous we are now passing parameters to the request of each DS fetch within the loop and avoiding dependency of one fetch over the other.

          But I wanted to know if there is any other way to pass data along the series of nested fetches other than passing it through the request as a request attribute? The values of these attributes may change along the path of DS fetches.

          Vinod

          Comment


            #6
            If you need to do a series of dependent fetches (each fetch needs data from the last), the only way to do this synchronously is on the server side.

            The Transaction Chaining feature can be used to do this declaratively, or, you can just use "new DSRequest()" in a DMI to issue multiple different fetches as part of processing a single fetch DSRequest submitted from the browser.

            Comment

            Working...
            X