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

PanelFrontend not working on cloud due to too low refetchInterval #14786

Open
5 tasks done
MarcSkovMadsen opened this issue Sep 19, 2022 · 9 comments
Open
5 tasks done
Labels
app:frontend lightning_app.frontend bug Something isn't working won't fix This will not be worked on

Comments

@MarcSkovMadsen
Copy link
Contributor

MarcSkovMadsen commented Sep 19, 2022

First check

  • I'm sure this is a bug.
  • I've added a descriptive title to this bug.
  • I've provided clear instructions on how to reproduce the bug.
  • I've added a code sample.
  • I've provided any other important info that is required.

Bug description

I'm trying to deploy some Panel apps with the PanelFrontend to --cloud as described in the lightning PanelFrontend documentation. But the app never shows up

I can see it keeps sending requests to root.lit_panel

image

After looking at the code I can the there is a refetchInterval of 1 second. This will probably never work for the PanelFrontend. The initial response will be more than 1 second as soon as the app is loading data initially or the server is in US and I am in Europe. You have to set it to 10 or 30 seconds for PanelFrontend apps.

image

How to reproduce the bug

Create a PanelFrontend a described in https://lightning.ai/lightning-docs/workflows/add_web_ui/panel/basic.html

requirements.txt

holoviews
pandas
panel>=0.13.1
plotly
hvplot

app_panel.py

import panel as pn
import hvplot.pandas

# Load Data
from bokeh.sampledata.autompg import autompg_clean as df

# Define Panel widgets
cylinders = pn.widgets.IntSlider(name='Cylinders', start=4, end=8, step=2)
mfr = pn.widgets.ToggleGroup(
    name='MFR',
    options=['ford', 'chevrolet', 'honda', 'toyota', 'audi'], 
    value=['ford', 'chevrolet', 'honda', 'toyota', 'audi'],
    button_type='success')
yaxis = pn.widgets.RadioButtonGroup(
    name='Y axis', 
    options=['hp', 'weight'],
    button_type='success'
)

# Define plotting function 
def plot(cylinders, mfr, yaxis):
    return (
        df[
            (df.cyl == cylinders) & 
            (df.mfr.isin(mfr))
        ]
        .groupby(['origin', 'mpg'])[yaxis].mean()
        .to_frame()
        .reset_index()
        .sort_values(by='mpg')  
        .reset_index(drop=True)
        .hvplot(x='mpg', y=yaxis, by='origin', color=["#ff6f69", "#ffcc5c", "#88d8b0"], line_width=6, height=400)
    )
    
# Bind plotting function with widgets 
interactive_plot = pn.bind(plot, cylinders, mfr, yaxis)

# Layout using Template
# Here we use the [FastListTemplate](https://panel.holoviz.org/reference/templates/FastListTemplate.html#templates-gallery-fastlisttemplate).
template = pn.template.FastListTemplate(
    title='Interactive DataFrame Dashboards with hvplot .interactive', 
    sidebar=[cylinders, 'Manufacturers', mfr, 'Y axis' , yaxis],
    main=[interactive_plot],
    accent_base_color="#88d8b0",
    header_background="#88d8b0",
)
template.servable()

app.py

import lightning as L
from lightning.app.frontend.panel import PanelFrontend


class LitPanel(L.LightningFlow):

    def configure_layout(self):
        return PanelFrontend("app_panel.py")


class LitApp(L.LightningFlow):
    def __init__(self):
        super().__init__()
        self.lit_panel = LitPanel()

    def configure_layout(self):
        return {"name": "home", "content": self.lit_panel}


app = L.LightningApp(LitApp())

Then deploy to the cloud

lightning run app app.py --cloud

Error messages and logs

See errors above

@MarcSkovMadsen MarcSkovMadsen added bug Something isn't working needs triage Waiting to be triaged by maintainers labels Sep 19, 2022
@MarcSkovMadsen
Copy link
Contributor Author

Part of the explanation might also be the low CPU provided

image

Before creating the PanelFrontend I used a LightningWork and there I got more cpu

image

image

@MarcSkovMadsen
Copy link
Contributor Author

MarcSkovMadsen commented Sep 20, 2022

I've now updated panel_app.py to

import panel as pn
import hvplot.pandas
import param

class App(param.Parameterized):
    loaded = param.Boolean()

app = App()

indicator = pn.indicators.LoadingSpinner(width=50, height=50, value=True, color="dark")

pn.extension(sizing_mode="stretch_width")

def load_data():
    from bokeh.sampledata.autompg import autompg_clean as df
    return df

cylinders = pn.widgets.IntSlider(name='Cylinders', start=4, end=8, step=2)
mfr = pn.widgets.ToggleGroup(
    name='MFR',
    options=['ford', 'chevrolet', 'honda', 'toyota', 'audi'], 
    value=['ford', 'chevrolet', 'honda', 'toyota', 'audi'],
    button_type='success')
yaxis = pn.widgets.RadioButtonGroup(
    name='Y axis', 
    options=['hp', 'weight'],
    button_type='success'
)

def selections():
    return pn.Column(cylinders, "MFR", mfr, "Cylinders", yaxis)

# Define plotting function 
def plot(cylinders, mfr, yaxis):
    if not mfr:
        return "No mfr selected"
    df = pn.state.as_cached("df", load_data)
    return (
        df[
            (df.cyl == cylinders) & 
            (df.mfr.isin(mfr))
        ]
        .groupby(['origin', 'mpg'])[yaxis].mean()
        .to_frame()
        .reset_index()
        .sort_values(by='mpg')  
        .reset_index(drop=True)
        .hvplot(x='mpg', y=yaxis, by='origin', color=["#ff6f69", "#ffcc5c", "#88d8b0"], line_width=6, height=400)
    )
    
# Bind plotting function with widgets 
interactive_plot = pn.bind(plot, cylinders, mfr, yaxis)

def sidebar(loaded=False):
    print("updated", loaded)       
    if not loaded:
        return indicator
    else:
       return selections
    

def main(loaded=False):
    if not loaded:
        return indicator
    else:
        return interactive_plot

isidebar = pn.bind(sidebar, loaded=app.param.loaded)
imain = pn.bind(main, loaded=app.param.loaded)

def loaded():
    app.loaded=True
    
pn.state.onload(loaded)

# Layout using Template
# Here we use the [FastListTemplate](https://panel.holoviz.org/reference/templates/FastListTemplate.html#templates-gallery-fastlisttemplate).
template = pn.template.FastListTemplate(
    title='Interactive DataFrame Dashboards with hvplot .interactive', 
    sidebar=[loaded, isidebar],
    main=[imain],
    accent_base_color="#88d8b0",
    header_background="#88d8b0",
)
template.servable()

This provides a faster initial response and can load the app but it is still very, very slow to update when I change the value in a widget. It is not slow locally at all.

@tchaton
Copy link
Contributor

tchaton commented Sep 20, 2022

Hey @MarcSkovMadsen

I believe the 0.3 CPU is probably the main reason why it is so slow. There are already several processes running in the flow container such as the flow and the Rest API.

I have 2 questions for you:

  • Could we automate your trick to enable a fast start time for the panel users?
  • Could you try to run the panel server within a work ? Normally, it would get 1 CPU. I think it would be good to evaluate the panel responsiveness and enable users to customize the flow specs.

@MarcSkovMadsen
Copy link
Contributor Author

I think the second bullet is the best option. Is there a way to increase the cpu for the root @tchaton?

@tchaton
Copy link
Contributor

tchaton commented Sep 21, 2022

Hey @MarcSkovMadsen.

For the flow, this is being added this sprint. For the works, you can pass a CloudCompute to the work.

@awaelchli awaelchli added app:frontend lightning_app.frontend and removed needs triage Waiting to be triaged by maintainers labels Sep 24, 2022
@MarcSkovMadsen
Copy link
Contributor Author

MarcSkovMadsen commented Sep 25, 2022

Hi @tchaton

I tried to figure out how to run the PanelFrontend with a work. I tried various combinations of code and I also looked through the documentation. I simply cannot figure out how to do this.

I don't find any examples running a Frontend as a work. It actually makes me wonder if you can? It makes me wonder if implementing support for Panel as a Frontend makes sense at all?

Before being guided to make a Frontend I implemented a Work for Panel.

I can also see that Jupyter is implemented as a Work in this example https://github.com/Lightning-AI/LAI-Jupyter-Component/blob/main/lai_jupyter/component.py.

Looking at the PanelFrontend implementation I also see a self.flow in the guide (similar for StreamlitFrontend), so aren't Frontends only useful for Flows?

image

Can you provide a minimum, reproducible example of running the PanelFrontend as/ within a work? Thanks.

If I can learn how to do it, I would love to contribute an example to the docs.

@stale
Copy link

stale bot commented Oct 29, 2022

This issue has been automatically marked as stale because it hasn't had any recent activity. This issue will be closed in 7 days if no further activity occurs. Thank you for your contributions, PyTorch Lightning Team!

@stale stale bot added the won't fix This will not be worked on label Oct 29, 2022
@MarcSkovMadsen
Copy link
Contributor Author

I should work on this. Just working on another thing right now

@stale stale bot removed the won't fix This will not be worked on label Oct 30, 2022
@stale
Copy link

stale bot commented Apr 14, 2023

This issue has been automatically marked as stale because it hasn't had any recent activity. This issue will be closed in 7 days if no further activity occurs. Thank you for your contributions - the Lightning Team!

@stale stale bot added the won't fix This will not be worked on label Apr 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
app:frontend lightning_app.frontend bug Something isn't working won't fix This will not be worked on
Projects
None yet
Development

No branches or pull requests

3 participants