Fix memory leak: ExecutionEngine recreated per query appending to global function registry#5222
Conversation
…bal function registry The OpenSearchExecutionEngine was not scoped as @singleton in the Guice module, causing a new instance to be created for every SQL/PPL request via injector.getInstance(SQLService.class). Each construction called registerOpenSearchFunctions(), which appended entries to the static PPLFuncImpTable.INSTANCE.externalFunctionRegistry via compute(). After N queries, the GEOIP function list contained N entries (each holding GeoIpFunction, SqlIdentifier, CalciteFuncSignature, PPLTypeChecker, etc.), leading to ~2GB heap retention after ~730K queries. Fix: 1. Add @singleton to the ExecutionEngine provider in OpenSearchPluginModule so only one instance is created per Guice injector. 2. Change registerExternalOperator() from compute()/append to put()/replace so repeated registrations overwrite instead of accumulating. Signed-off-by: Kai Huang <kaihuang@amazon.com> Signed-off-by: Kai Huang <ahkcs@amazon.com>
PR Code Analyzer ❗AI-powered 'Code-Diff-Analyzer' found issues on commit a77e23b.
The table above displays the top 10 most important findings. Pull Requests Author(s): Please update your Pull Request according to the report above. Repository Maintainer(s): You can Thanks. |
PR Reviewer Guide 🔍(Review updated until commit 1d661ac)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to 1d661ac
Previous suggestionsSuggestions up to commit a77e23b
|
Signed-off-by: Kai Huang <kaihuang@amazon.com> Signed-off-by: Kai Huang <ahkcs@amazon.com>
|
Persistent review updated to latest commit 1d661ac |
RyanL1997
left a comment
There was a problem hiding this comment.
Can you confirm that registerExternalOperator is never called more than once for the same BuiltinFunctionName? The old compute() logic accumulated overloads, while the new put() replaces them. If single-registration is guaranteed, this simplification LGTM. Also, please verify that no downstream code mutates the list retrieved from externalFunctionRegistry, since List.of() is immutable.
|
Summary
OpenSearchPluginModule.executionEngine()was missing@Singleton, so Guice created a newOpenSearchExecutionEngineon every SQL/PPL request. Each construction calledregisterOpenSearchFunctions(), which appended toPPLFuncImpTable.INSTANCE.externalFunctionRegistryviacompute()— growing the list by 1 entry per query, forever.