question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Implement update echo messages in a backward-compatible way

See original GitHub issue

I think we can implement the update echo feature from https://github.com/jupyter-widgets/ipywidgets/pull/3195 and further discussed in https://github.com/jupyter-widgets/ipywidgets/pull/3343 in a backward-compatible way.

To summarize, when the kernel receives an update message, it will apply the message and then always broadcast out a message to clients, where some of the attribute updates in the broadcast message may be designated as echoed updates. Clients ignore echoed updates until their own update is echoed back to them. They should ignore because it lets them optimistically update their own UX. Essentially, seeing the echo of their own update lets them know the order in which the kernel is applying updates from multiple clients, and ignore those echoed updates if it knows that the kernel still has to apply its own update.

If a client does not ignore echo updates until it sees its own update echoed, and if the client is optimistically updating its own UX to reflect its update, we will have jitter. For example, imagine two clients displaying the same slider model, and both sliders are being dragged, and slider A sends a message updating the value to 5 while slider B sends a message updating the value to 10. Each slider is updated to its own update value, but we don’t have consensus on what the kernel is going to pick. The kernel processes these messages in order, and sends out slider A’s update as an echo, then slider B’s update as an echo. Slider A receives its own echoed update, then B’s echoed update, and applies B’s update since it came after its own echo. However, slider B receives A’s echoed update and ignores it, since it knows the kernel has yet to apply its own update. Then slider B receives its own echoed update, which it can ignore since it has already updated the UX optimistically for that value. The end result is that both clients and the kernel have agreed that B’s update wins.

We said this protocol wasn’t backwards compatible since if B doesn’t know to ignore comm echo updates, it will jitter since it will apply A’s update, then apply its own echo update. The real problem, though, is that the echo updates and normal updates are intermingled in the single key in the update message, so a client that doesn’t know about comm echo updates cannot distinguish between the two types of updates.

However, what if we send echoed state updates in their own echo_state key, rather than conflating it with the normal state key for normal updates from the kernel? Then I think things are backwards compatible - clients that don’t know about the echoed updates will ignore any echoed updates, so there is no change in their behavior. Clients that understand the echoed update messages can implement this consensus protocol from above. I think in this case, we can implement this logic in 7.7, to give it to people that won’t be able to update to 8.0 right away.

Disclosure: At Databricks, my current employer, we’d like to get this feature in 7.7 if we can, which led me to reevaluating the problem to see if there was a way we could do it in a backwards compatible way.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:2
  • Comments:11 (10 by maintainers)

github_iconTop GitHub Comments

2reactions
jasongroutcommented, Feb 19, 2022

In other words, I’m suggesting that the protocol be amended this way:

Synchronizing multiple frontends: update with echo

Starting with protocol version 2.1.0 the kernel can send a special update message back, to allow all connected frontends to be in sync with the kernel state. This allows multiple frontends to be connected to a single kernel but also resolves a possible out of sync situation when the kernel and a frontend send out an update message at the same time, causing both to think they have the latest state.

In protocol version 2.1.0 the kernel is considered the single source of truth and is expected to send back to the frontends an update message that contains an extra state update dictionary indicating which state updates are just reflections of frontend state updates.

{
  'comm_id' : 'u-u-i-d',
  'data' : {
    'method': 'update',
    'state': { <dictionary of widget state> },
    'echo_state': { <dictionary of widget state> },
    'buffer_paths': [ <list with paths corresponding to the binary buffers> ]
  }
}

The state dictionary contains updates directly from the kernel, while echo_state contains updates from other frontends. If the same attribute is in both dictionaries, the state update takes precedence. state must be present, but may be empty, and echo_state is optional.

In situations where a user does many changes to a widget on the frontend (e.g. moving a slider), the frontend will receive from the kernel many update messages (with the echo_state key containing echoed updates) from the kernel that can be considered old values. A frontend can choose to ignore all updates in echo_state that are not originating from the last update it send to the kernel. This can be implemented by keeping track of the msg_id for each attribute for which we send out an update message to the kernel, and ignoring all echo_state updates as a result from an echo for which the msg_id of the parent header is not equal to msg_id we kept track of.

For situations where sending back an echo update for a property is considered to expensive, we have implemented an opt-out mechanism in ipywidgets. A trait can have a no_echo metadata attribute to flag that the kernel should not send back an update to the frontends. We suggest other implementations implement a similar opt-out mechanism.

1reaction
vidartfcommented, Feb 22, 2022

We should try to capture all corner cases in tests

@maartenbreddels already did some good work on this, much appreciated.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Protocol Buffers Best Practices for Backward and Forward ...
If a message is changed and a non-updated client can still understand and process the message then the message change is forward compatible....
Read more >
Major version behavior and compatibility differences
MINOR versions are for new functionality added in a backwards-compatible way. PATCH versions are for backwards-compatible bug fixes and non-functional changes.
Read more >
Ensuring backwards compatibility in distributed systems
One of these is maintaining backwards compatibility between components. In other words, how can a set of services evolve together in a way...
Read more >
Backward incompatible changes - Manual - PHP
This migration guide will merely enumerate the changes that affect backward compatibility. set_exception_handler() is no longer guaranteed to receive Exception ...
Read more >
Alexa Command Guide: All the Voice Commands You Need to ...
We compiled the complete list of commands you can give to Amazon's Alexa on any of your Echo devices.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found