Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fast updates on ValueDownLink via runtime client are not send? #45

Closed
msche opened this issue Feb 3, 2020 · 3 comments
Closed

Fast updates on ValueDownLink via runtime client are not send? #45

msche opened this issue Feb 3, 2020 · 3 comments

Comments

@msche
Copy link

msche commented Feb 3, 2020

I created a setup in which I have a Agent with a swim lane for a double and a Java client which updates it from 0 to 1000.

Client

value = client.downlinkValue()
        .valueForm(Form.forDouble())
        .keepSynced(true)
        .keepLinked(true)
        .hostUri("warp://localhost:9001").nodeUri("/Input/" + uuid).laneUri("value");
value.open();
for (double i=0; i<1000; i++) {
    value.set(i);
    //Thread.sleep(100)
}
value.close();

On the ValueLane I have added a didSet handler that outputs the value to the console.

public class Input extends AbstractAgent {

    @SwimLane("value")
    ValueLane<Double> value = this.<Double>valueLane()
            .didSet((newValue, oldValue) -> {
                System.out.println("observed info change to " + newValue + " from " + oldValue);
            });

}

When I run the client without delay between the setting of the double value, only the last value change is printed (observed info change to 999.0 from 0.0). When I put a thread sleep of 100 between the set all changes to the value are printed.

@SirCipher
Copy link
Member

Hi @msche, thank you for reporting this. The issue that you're experiencing is #36 and it's currently under investigation. The workaround for this at the moment is to sleep the thread in between setting the value of the downlink - as you are doing.

@ajay-gov
Copy link
Member

ajay-gov commented Feb 5, 2020

Hi @msche, thanks for reporting this. Issue #36 occurs when we spam the downlink for a really long time with a heavy load. Since you are seeing the last messages you are not encountering that problem.

There are two reasons why you are seeing this behavior.

  1. value.open() is an asynchronous call which opens a connection to the server (to that specific Web Agent and Lane). So most of the calls to value.set are invoked prior to the downlink being established. Ideally you should start sending messages once the link is established. You should use the didSync callback on the downlink which gets invoked when a link is established and synced.
    So you should call value.set in that code block. Something like this:
ValueDownlink<Double> value = client.downlinkValue()
        .valueForm(Form.forDouble())
        .keepSynced(true)
        .hostUri("warp://localhost:9001").nodeUri("/Input/1").laneUri("value");
    value.open();
    value.didSync(new DidSync() {
      @Override
      public void didSync() {
        for (double i=0; i<1000; i++) {
          value.set(i);
          //Thread.sleep(100);
        }
        value.close();
      }
  1. Even with the above change you may not be able to see all the data you send to the server. This is because Swim is a stateful platform which is based on propagating state changes. Both the Client and Server (Agents in a Swim Plane) maintain state. The 'state' is maintaied by Lanes in Web Agents (on the Server). The Client(s) maintain state by having a copy of the lane data. Downlinks use the WARP protocol to exchange state changes between Server and Client. When invoking value.set the client updates it's local copy and then proceeds to send the state change to the server. This is an asynchronous network call. However since you call set frequently in the loop these calls to set occur before the network call to propagate state to the server.

If your desired behavior is to receive all the messages sent from the client to the server then you need to use 'commands' instead of downlinks. Warp commands get propagated to the Web Agent on the server, the Web Agent will update it's lane and that state change which will get propagated to all downlinks to that lane from clients.
This would look like this:

for (double i=0; i<1000; i++) {
  client.command("warp://localhost:9001", "/Input/1", "value", Num.from(i));
}

Hopefully this is clear. Please do let us know if you have any questions.

@SirCipher SirCipher mentioned this issue Feb 12, 2020
@ajay-gov
Copy link
Member

ajay-gov commented May 1, 2020

Since this is either by design or it's been captured by issue 36

@ajay-gov ajay-gov closed this as completed May 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants