Fully stopping pond.observe?

Hi there,

I understand that the return type of a pond.observe is a cancelSubscription, which I initially thought totally cancel the subscription to the state change of the twin. However I realized that it just stops the callback of the observe, but does not stop the observation itself.

The use case I would like to achieve is a temporary observation, e.g. a robot monitoring the heartbeat (implemented in a dedicated heartbeat twin) of another robot, but only when the two are interacting. It does not make sense for all robots to monitor heartbeats of all other robots at all time (assuming there are more than 2 robots, but many)

Is there any way to fully stop a subscription? Or do you have other suggestion on how to implement such use-case?

thank you!

Hi Dipta,

each Fish in the Pond publishes its state changes to an RxJS Subject, which pond.observe() then gives you access to. The returned cancellation function indeed only unsubscribes from the Subject, it does not stop it from receiving updates.

One of the next features we’ll add to the Pond is the ability to stop updating fishes that haven’t been observed for some time and to remove them completely from memory — this should answer your concern of stopping the heartbeat processing for irrelevant robots. The time constants for this should probably be tuneable, may I ask what your use-case will require?

(BTW: the most immediately upcoming features will be that isReset actually makes Fish startup fast again and that local snapshots will be supported when using Actyx v2, putting fishes to sleep comes after that)

Regards,

Roland

Hi Roland, thank you for your reply.

So after using the cancelSubscription, what I found is that the app (i.e. robot terminal) still observing the update of the fish. I found this by adding a console.log in the fish’s onEvent. (before the pond.observe, this console.log does not show anything.) When you mention “does not stop it from receiving updates”, did you refer to the pond or the app?

In the current implementation, all robots emit a hearbeat event each second, and a robot will observe the hearbeat of another robot only when needed (e.g. when mechanically interacting). In my understanding what needed here is not stopping updating the fish (i.e. stop emitting the heartbeat), but instead, stopping observing a heartbeat. Will this be supported as well?

The improvement of the isReset will certainly be a helpful one. Currently each robot is emitting a heartbeat event using a heartbeat twin, using isReset. And as you mentioned, the startup is still slow since all past heartbeats event will be processed.

best regards,
Dipta

Hi Dipta,

the structure roughly is as follows:

Actyx → HTTP API → onEvent → RxJS Subject → observer

With all Pond versions so far, this chain is set up when you first interact with the Fish, and the four first pieces remain active afterwards as long as the Pond lives. The only thing that can be canceled is the final observer.

For your use-case, if all your Fish does is to observe a heartbeat, you may be better served by using the SDK directly. In the case of heartbeats it may even be that you don’t need to see all of them, only the latest (to judge whether the robot has sent something within the last few seconds):

let myState = initialState(...)
// the Pond has an Actyx SDK instance inside; otherwise use Actyx.of(manifest)
let cancel = pond.events().observeLatest(robotTags, (event, meta) => {
  myState = onEvent(myState, event, meta)
})

With this approach you are in full control when the event delivery will stop. If you need all intermediate events (e.g. for keeping statistics), you can use subscribe instead of observeLatest — the difference to using the Pond is that you’ll sometimes see events delivered out of order.

Regards,

Roland

Ah this might be what I need.
Yes, exactly, the observer robot just needs to know when was the last time the other robot was “alive”. If it had been more than a few seconds, it would raise an alert. Therefore, the intermediate events are not important.
I’ll try this and let you know the result later.

1 Like

Hi Roland,

I have tried your suggestion and it works well for my use case.
I just needed to change the suggested code a little bit, because I kept getting error if I don’t pass the query as an object using the query key:

let cancel = pond.events().observeLatest({query:robotTag.withId(partnerId)}, (event, meta) => {
  //app logic here
})

I don’t event need a fish for this one, since the app will handle the event directly.

Thank you for your help!
best regards,
Dipta

Yes, my bad, the query does indeed need to be passed like that. Thanks for confirming this approach, and let us know if you encounter any other difficulty!