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

Issue: memory leak when using rowTransaction #338

Open
andre996 opened this issue Nov 5, 2024 · 0 comments
Open

Issue: memory leak when using rowTransaction #338

andre996 opened this issue Nov 5, 2024 · 0 comments
Labels
bug something broken

Comments

@andre996
Copy link

andre996 commented Nov 5, 2024

Description:

when using rowTransactions. Every time a transaction is performed, a memory leak occurs. This is due to new row references being created while old ones aren’t being removed, leading to an increase in Shallow Size and Retained Size.

Image

Sample code:

import dash_ag_grid as dag
from dash import Dash, html, Input, Output, State, ctx, no_update, callback

app = Dash(__name__)

rowData = [
    {"id": "Toyota_0", "make": "Toyota", "model": "Celica", "price": 35000},
    {"id": "Ford_0", "make": "Ford", "model": "Mondeo", "price": 32000},
    {"id": "Porsche_0", "make": "Porsche", "model": "Boxster", "price": 72000},
]

columnDefs = [
    {"field": "id", "checkboxSelection": True, "headerCheckboxSelection": True},
    {"field": "make"},
    {"field": "model"},
    {"field": "price", "cellRenderer": "agAnimateShowChangeCellRenderer", },
]

columnDefs_leet = [
    {"field": "id",  'headerName':  "DSFDS","checkboxSelection": True, "headerCheckboxSelection": True},
    {"field": "make", 'headerName': "DFA VXC" ,},
    {"field": "model", 'headerName': "DSS Z",},
    {"field": "price", 'headerName': "SDEAW", "cellRenderer": "agAnimateShowChangeCellRenderer", },
]


app.layout = html.Div(
    [
        html.Button("Update column def", id="btn-header-names-toggle"),
        html.Button("Add Rows", id="btn-client-side-transaction-add"),
        html.Button("Add Rows at index 2", id="btn-client-side-transaction-add-index-2"),
        html.Button("Update selected", id="btn-client-side-transaction-update"),
        html.Button("Remove Selected", id="btn-client-side-transaction-remove"),
        html.Button("Clear", id="btn-client-side-transaction-clear"),
        html.Button("Start Over", id="btn-client-side-transaction-start"),
        dag.AgGrid(
            id="client-side-transaction",
            rowData=rowData,
            columnDefs=columnDefs,
            columnSize="sizeToFit",
            dashGridOptions={"rowSelection": "multiple"},
            getRowId="params.data.id"
        ),
    ],
)

@callback(
    Output("client-side-transaction", "columnDefs"),
    Input("btn-header-names-toggle", "n_clicks"),
     State("client-side-transaction", "columnDefs"),
    prevent_initial_call=True
)
def toggle_cols(n, column_defs):
    if n % 2 == 0:
        return columnDefs
    return columnDefs_leet
    # print('Changing column def')
    # for col in column_defs:
    #     col["valueFormatter"] = {"function": "'* ' + params.value + ' *'"}
    # print(column_defs)
    # return columnDefs

@callback(
    Output("client-side-transaction", "rowData"),
    Input("btn-client-side-transaction-clear", "n_clicks"),
    Input("btn-client-side-transaction-start", "n_clicks"),
)
def update_rowdata(*_):
    return [] if ctx.triggered_id == "btn-client-side-transaction-clear" else rowData


@callback(
    Output("client-side-transaction", "rowTransaction"),
    Input("btn-client-side-transaction-add", "n_clicks"),
    Input("btn-client-side-transaction-add-index-2", "n_clicks"),
    Input("btn-client-side-transaction-update", "n_clicks"),
    Input("btn-client-side-transaction-remove", "n_clicks"),
    State("client-side-transaction", "selectedRows"),
    prevent_initial_call=True,
)
def update_transaction(n1, n2, n3, n4, selection):
    if ctx.triggered_id in ["btn-client-side-transaction-add", "btn-client-side-transaction-add-index-2"]:
        newRows = [
            {
                "id": row["make"] + '_' + str((n1 or 0) + (n2 or 0)),
                "make": row["make"], "model": row["model"], "price": row["price"]
            } for row in rowData
        ]

        return (
            {"add": newRows}
            if ctx.triggered_id == "btn-client-side-transaction-add"
            else {"add": newRows, 'addIndex': 2}
        )

    if selection:
        if ctx.triggered_id == "btn-client-side-transaction-update":
            for row in selection:
                row["price"] = row["price"] + n3
            return {"update": selection}

        if ctx.triggered_id == "btn-client-side-transaction-remove":
            return {"remove": selection}

    # If no rows selected, no grid update
    return no_update


if __name__ == "__main__":
    app.run(debug=True)

Ref: https://dash.plotly.com/dash-ag-grid/client-side#transaction-updates

FYI: There is also an increase of memory use with rowData but it is smaller

@gvwilson gvwilson added the bug something broken label Nov 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug something broken
Projects
None yet
Development

No branches or pull requests

2 participants