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

[OTHER] UI much slower when running in Docker than on host #2417

Open
1 of 2 tasks
LMaiorano opened this issue Jan 21, 2025 · 1 comment
Open
1 of 2 tasks

[OTHER] UI much slower when running in Docker than on host #2417

LMaiorano opened this issue Jan 21, 2025 · 1 comment
Labels
🖧 Devops Operations, monitoring, maintenance, deployment, packaging 🖰 GUI Related to GUI 💥Malfunction Addresses an identified problem. 🟧 Priority: High Must be addressed as soon 🔒 Staff only Can only be assigned to the Taipy R&D team

Comments

@LMaiorano
Copy link

LMaiorano commented Jan 21, 2025

What would you like to share or ask?

Hi,

I'm currently running a Taipy application inside a Docker container. I've noticed a significant slowdown in UI responsiveness compared to when I run it on the host. I've already looked into the usual suspects such as: running the container as --privileged, using a -slim python base image, resource availability, and container file systems. None of these resolve the issue. This issue has also been reproduced on another machine.

On further inspection, it appears the issue lies when Plotly figures (stored as state variables) are updated with new figures. In the first code snippet below, you can see the order of execution. When running on the host, the log message and figure refresh in the UI are nearly simultaneous. Inside a docker container, the figures refresh approximately 5 seconds after the log message.

def status_LRCB_update_plots(state, status, result_figures):
    if isinstance(status, bool):
        if status:
            fig_1, fig_2, fig_3 = result_figures

            state.fig_1 = fig_1
            state.fig_2 = fig_2
            state.fig_3 = fig_3
            logger.debug("Plot update complete")

The long-running-callback is started by a UI on_change callback:

def callback_year_filter(state, var_name, value):
    """Callback for year filter"""
    # reload plots here
    state.year_filter_value = value  
    update_plots(state, LCRB_status_function=status_LRCB_update_plots)


def update_plots(state, LCRB_status_function):
    """'Update plots based on filters"""
    
    data = (
        state.dataset
        # Apply year filter
        .filter(pl.col("year").is_in([int(j) for j in state.year_filter_value]))
    ).collect()

    logger.debug("Starting plot update")
    tpgui.invoke_long_callback(
        state=state,
        user_function=LRCB_update_plots,
        user_function_args=[
            data
        ], 
        user_status_function=LCRB_status_function,
    )


def LRCB_update_plots(df_grouped):
    '''Update plots based on filters, this runs in a seperate thread'''

    fig_1 = px.bar(
        df_grouped,
        x='years',
        y='count',
        title='Number of objects per year',
    )
    
    fig_2 = px.bar(
        df_grouped,
        x='objecttype',
        y='count',
        title='Number of objects per objecttype',
    )
    
    fig_3 = px.bar(
        df_grouped,
        x='ap3',
        y='count',
        title='Number of objects per AP3',
    )
    
    return fig_1, fig_2, fig_3

Dockerfile:

# STAGE 1: Use same base image for all stages for optimal caching
FROM python:3.12-slim-bookworm AS base

FROM base AS builder
# Install the uv package manager
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv
# Use bytcode compilation for faster startup and uv link mode to copy python files into container
ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy


# # STAGE 2: Set working directory and copy uv project files into the image
WORKDIR /app
COPY uv.lock pyproject.toml /app/

# uv sync will install the project dependencies, excluding dev dependencies
# with caching and bind mounts to optimize the build process.
RUN --mount=type=cache,target=/root/.cache/uv \
    --mount=type=bind,source=uv.lock,target=uv.lock \
    --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
    uv sync --frozen --no-install-project --no-group dev

# After dependencies are installed, copy the rest of the project files into the image
COPY taipy_dashboard /app

RUN --mount=type=cache,target=/root/.cache/uv \
    uv sync --frozen --no-group dev


# STAGE 3: Copy builder from base image and start the final image
# final image without uv
FROM base AS final
# Copy the application from the builder
COPY --from=builder --chown=app:app /app /app

# Single file copy so the app version can be read from the file
# Pyproject.toml is copied into one directory above the project directory to match the relative path
COPY pyproject.toml /pyproject.toml

# Place executables in the environment at the front of the path
ENV PATH="/app/.venv/bin:$PATH"

WORKDIR /app
# Run the Taipy application using python
EXPOSE 5000
ENTRYPOINT [ "python", "main.py", "-P", "5000", "-H", "0.0.0.0", "--no-reloader" ]

pyproject.toml:

[project]
name = "tp_dashboard"
readme = "README.md"
version = "1.1.3"
requires-python = ">=3.12"
dependencies = [
    "numpy==1.26.4",
    "pandas==2.2.2",
    "loguru==0.7.3",
    "python-dotenv==1.0.1",
    "plotly==5.24.1",
    "pyarrow==17.0.0",
    "polars==1.16.0",
    "taipy==4.0.2",
    "connectorx==0.4.0"
]

Due to confidentiality, I unfortunately cannot share the full source code. However, I hope someone can provide some insight into what occurs in the backend of Taipy when a figure state variable is overwritten by a new figure object.

The dashboard is very responsive and running smoothly up until the point where the new figures are saved to the state variables in (status_LRCB_update_plots()). No other LRCB's or functions are running at the same time.

Is this a computationally "expensive" operation? Does Docker's network cause the delay here?

Has anyone else experienced something similar?
What happens on the Taipy backend that could cause a slow UI refresh inside a Docker container?

Thanks in advance for any help here!

Code of Conduct

  • I have checked the existing issues.
  • I am willing to work on this issue (optional)

(edited for formatting)

@jrobinAV jrobinAV added 🖧 Devops Operations, monitoring, maintenance, deployment, packaging 🖰 GUI Related to GUI 💥Malfunction Addresses an identified problem. 🟧 Priority: High Must be addressed as soon 🔒 Staff only Can only be assigned to the Taipy R&D team labels Jan 24, 2025
@FlorianJacta
Copy link
Member

FlorianJacta commented Jan 24, 2025

Could you help us with how much data you use (the volumetry behind it)?

Can you also check the network traffic (F12 on the navigator)?

Are you running Docker locally?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🖧 Devops Operations, monitoring, maintenance, deployment, packaging 🖰 GUI Related to GUI 💥Malfunction Addresses an identified problem. 🟧 Priority: High Must be addressed as soon 🔒 Staff only Can only be assigned to the Taipy R&D team
Projects
None yet
Development

No branches or pull requests

3 participants