plotly / plotly/dash

dcc.interval missed triggering callback on time

Open
#2,186 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug P3
Dominant language
Python
Stars
24.4k
Forks
2.3k
Avg merge
2d 7h
Merged PRs (30d)
13

Description

Hi Dash Admin,

Environment

Package                   Version
------------------------- -------
dash                      2.6.1
dash-bootstrap-components 0.13.1
dash-core-components      2.0.0
dash-daq                  0.5.0
dash-html-components      2.0.0
dash-table                5.0.0

Frontend (P/S: You don't need browser to reproduce the issue below):

- OS: Windows 11
- Browser: Chrome
- Version: 103.0.5060.134 (64-bit)

Describe the bug
Using the simple Python script below, the intention is to confirm the time for dcc.interval component to trigger callback as specified by the interval parameter. The screenshot below captured what had happened after the script ran for about 30 seconds. The callback was fired neither according to the 1 second interval nor consistent with 1 second interval. In fact, it was fired twice within the gap of 100ms to 300ms. You may find the additional notes within the screenshot dump itself.

Expected behavior
dcc.interval should fire callback precisely at interval of 1 second and consistently doing so. It should NOT fire the callback twice (with gap of 100ms and 300ms), making it clearly it is a defect. I suspect this issue is not newly introduced in Dash 2.x.x as I've seen similar behavior in Dash 1.x.x as well.

I would appreciate if someone from your team will look into this issue as this should be a fundamental functionality of dcc.interval component and it has been missed out by your test coverage since long ago.

Thank you in advance for your attention.

Codes

import dash
import datetime
import inspect

from dash.dependencies import Input, Output
from dash import html
from dash import dcc

app = dash.Dash(__name__)

app.layout = html.Div([
    dcc.Interval(id='my_interval', disabled=False, n_intervals=0, interval=1000 * 1),
    html.Div("Counter: ", style={"display": "inline-block"}),
    html.Div(children=None, id="cnt_val", style={"display": "inline-block", "margin-left": "15px"}),
])

@app.callback(
    Output('cnt_val', 'children'),
    [Input('my_interval', 'n_intervals')]
)
def update(n_intervals):
    timer_label__children = ""
    print("{} Line: {}: {}".format(
        inspect.getframeinfo(inspect.currentframe()).function,
        inspect.getframeinfo(inspect.currentframe()).lineno,
        datetime.datetime.now().isoformat().replace("T", " "),
    ))
    return timer_label__children


app.run_server(debug=True)

Screenshots

python.exe dcc_interval_missed_triggering_callback.py 
Dash is running on http://127.0.0.1:8050/

 * Serving Flask app 'dcc_interval_missed_triggering_callback' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
update Line: 25: 2022-08-09 17:55:13.380438
update Line: 25: 2022-08-09 17:55:13.410408 (~+100ms)
update Line: 25: 2022-08-09 17:55:14.663830 (~+1.2s)
update Line: 25: 2022-08-09 17:55:14.690467 (~+300ms)
update Line: 25: 2022-08-09 17:55:16.666802 (~+2s)
update Line: 25: 2022-08-09 17:55:16.694578 (~+300ms)
update Line: 25: 2022-08-09 17:55:18.674646 (~+2s)
update Line: 25: 2022-08-09 17:55:18.709329 (~+300ms)
update Line: 25: 2022-08-09 17:55:20.668811
update Line: 25: 2022-08-09 17:55:20.684814
update Line: 25: 2022-08-09 17:55:22.670781
update Line: 25: 2022-08-09 17:55:22.683749
update Line: 25: 2022-08-09 17:55:24.698829
update Line: 25: 2022-08-09 17:55:24.722054
update Line: 25: 2022-08-09 17:55:26.672720
update Line: 25: 2022-08-09 17:55:26.706718
update Line: 25: 2022-08-09 17:55:28.667662
update Line: 25: 2022-08-09 17:55:28.694618
update Line: 25: 2022-08-09 17:55:30.697895
update Line: 25: 2022-08-09 17:55:30.716306
update Line: 25: 2022-08-09 17:55:32.676514
update Line: 25: 2022-08-09 17:55:32.700857
update Line: 25: 2022-08-09 17:55:34.688452
update Line: 25: 2022-08-09 17:55:34.703525
update Line: 25: 2022-08-09 17:55:36.672344
update Line: 25: 2022-08-09 17:55:36.691374
update Line: 25: 2022-08-09 17:55:38.670202
update Line: 25: 2022-08-09 17:55:38.695352
update Line: 25: 2022-08-09 17:55:40.679620
update Line: 25: 2022-08-09 17:55:40.708878
update Line: 25: 2022-08-09 17:55:42.674115
update Line: 25: 2022-08-09 17:55:42.703361
update Line: 25: 2022-08-09 17:55:44.679233
update Line: 25: 2022-08-09 17:55:44.717429

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the supplied Python reproduction and compare the callback timestamps with the one-second interval. Trace the dcc.Interval callback path and add regression coverage for duplicate or delayed triggers; done means callbacks no longer occur in pairs or at roughly two-second gaps.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.