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

fix(dashboard): use server-side lastModifiedTime for co-edit check #11614

Merged

Conversation

graceguo-supercat
Copy link

@graceguo-supercat graceguo-supercat commented Nov 8, 2020

SUMMARY

In #11220 and #11305, we introduced a feature that prevent mid-air collision when 2 users editing same dashboard. There are some users in airbnb reported that when only 1 user editing dashboard a couple of times they will see the warning message, even there is no co-editing happens, see issue #11477

When i debug this issue, i found when error happens, it shows client-side last_updated_time and dashboard's changed_on has a very subtle mis-match, for example:

remote:1604869261.688
changed_on:1604869262.0

it seems dashboards table's changed_on is rounded-up to second level, while client-side last_update_time is not.
So i will add a round function in client-side and try to make this number match in the second level.

TEST PLAN

CI and manual test

ADDITIONAL INFORMATION

cc @ktmud @eschutho @mistercrunch @zuzana-vej

@codecov-io
Copy link

codecov-io commented Nov 8, 2020

Codecov Report

Merging #11614 (158fa13) into master (849e7e9) will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master   #11614   +/-   ##
=======================================
  Coverage   62.26%   62.26%           
=======================================
  Files         873      873           
  Lines       42256    42256           
  Branches     3961     3961           
=======================================
  Hits        26310    26310           
  Misses      15766    15766           
  Partials      180      180           
Flag Coverage Δ
javascript 62.83% <ø> (ø)
python 61.91% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...t-frontend/src/dashboard/reducers/dashboardInfo.js 66.66% <ø> (ø)
...-frontend/src/dashboard/reducers/dashboardState.js 73.33% <ø> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 849e7e9...158fa13. Read the comment docs.

@mistercrunch
Copy link
Member

Mmmh, it feels like using/comparing the client time and server time is a brittle approach as time zones and/or a wrong client clock would create problems.

Could we just rely on the server time stamp and use it as the equivalent of a version number? Meaning even when we save the server could return a payload with a new server side timestamp that we can stick into the redux store and send on the next save event a an equivalent to a version id.

@graceguo-supercat
Copy link
Author

graceguo-supercat commented Nov 9, 2020

Could we just rely on the server time stamp and use it as the equivalent of a version number? Meaning even when we save the server could return a payload with a new server side timestamp that we can stick into the redux store and send on the next save event a an equivalent to a version id.

Yes, i am also looking for a solution like that. Currently /save_dash/ API only response status without changed_on timestamp:
https://github.com/apache/incubator-superset/blob/29554a9f02264b7f619829cbe01dc6d5c25b30f8/superset/views/core.py#L1089

what is best way to get its changed_on after an update? (also need to apply same change to /api/v1/dashboard/ PUT API)

@graceguo-supercat
Copy link
Author

graceguo-supercat commented Nov 9, 2020

I pushed another solution: server-side returns last_modified_time (which is changed_on after latest update) in save_dash response. Front-end updates redux state, and send back this value for the next save request.

@graceguo-supercat graceguo-supercat changed the title fix: [dashboard][co-edit] Round client-side lastModifiedTime fix: [dashboard][co-edit] server-side returns lastModifiedTime Nov 9, 2020
@ktmud ktmud changed the title fix: [dashboard][co-edit] server-side returns lastModifiedTime fix(dashboard): use server-side lastModifiedTime for co-edit check Nov 9, 2020
Copy link
Member

@ktmud ktmud left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with one naming suggestion

session.close()
return json_success(json.dumps({"status": "SUCCESS"}))
return json_success(
json.dumps({"status": "SUCCESS", "last_modified_time": last_modified_time,})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we rename last_modified_time everywhere to changed_on if it's not too big of a change?

Having some consistency is nice.

Copy link
Author

@graceguo-supercat graceguo-supercat Nov 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed_on is a column name in Dashboards table, its type is DATETIME. I prefer to use utc timestamp (use it like version id) so that ignore local time etc (maybe different setup in each company).


# get updated changed_on
dash = session.query(Dashboard).get(dashboard_id)
last_modified_time = dash.changed_on.replace(microsecond=0).timestamp()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: .replace(microsecond=0) is probably not needed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i want to use timestamp in the second level, to avoid comparing 2 float number.

@graceguo-supercat graceguo-supercat merged commit b9284d3 into apache:master Nov 9, 2020
@mistercrunch
Copy link
Member

Hey side note (totally supportive of merging this!) but wanted to try and understand better how we prevent users from colliding with themselves. I think we have many ways that we update the dashboard definition (many modals)

Screen Shot 2020-11-09 at 1 43 11 PM

Do we check the version on all/some of the endpoints?

@graceguo-supercat
Copy link
Author

graceguo-supercat commented Nov 9, 2020

Do we check the version on all/some of the endpoints?

Hi @mistercrunch All the changes from dashboard header dropdown list, go through single API /save_dash/.
But changes in Dashboard Properties Modal, first save to /dashboard/api/v1, then save again to /save_dash/.
Please see my findings here: #10834 (comment)

Currently /dashboard/api/v1 don't check version, I will file a feature request to add version support.

graceguo-supercat pushed a commit to airbnb/superset-fork that referenced this pull request Nov 10, 2020
…pache#11614)

* fix: [dashboard][co-edit] Round client-side lastModifiedTime

* another try: server-side returns last_updated_time in save_dash response

(cherry picked from commit b9284d3)
auxten pushed a commit to auxten/incubator-superset that referenced this pull request Nov 20, 2020
…pache#11614)

* fix: [dashboard][co-edit] Round client-side lastModifiedTime

* another try: server-side returns last_updated_time in save_dash response
@mistercrunch mistercrunch added 🏷️ bot A label used by `supersetbot` to keep track of which PR where auto-tagged with release labels 🚢 1.0.0 labels Mar 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🏷️ bot A label used by `supersetbot` to keep track of which PR where auto-tagged with release labels size/M 🚢 1.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants