# HG changeset patch # User Sebastien Jodogne # Date 1693382977 -7200 # Node ID 35c0b2fc751cef895b10d7a86f6c0348db66bafe # Parent 5f0b7795afaf6fa22afbae2a20eacbee2b1b1aec added configuration section "Python" and option "DisplayMemoryUsage" diff -r 5f0b7795afaf -r 35c0b2fc751c NEWS --- a/NEWS Wed Aug 30 08:14:21 2023 +0200 +++ b/NEWS Wed Aug 30 10:09:37 2023 +0200 @@ -1,6 +1,12 @@ Pending changes in the mainline =============================== +* New configuration section "Python" to group settings related to the plugin: + - "Python.Path" is an alias for global option "PythonScript" + - "Python.Verbose" is an alias for global option "PythonVerbose" +* New configuration option "Python.DisplayMemoryUsage" to periodically + display memory allocations that stem from Python plugins + Version 4.0 (2022-02-23) ======================== diff -r 5f0b7795afaf -r 35c0b2fc751c Sources/Plugin.cpp --- a/Sources/Plugin.cpp Wed Aug 30 08:14:21 2023 +0200 +++ b/Sources/Plugin.cpp Wed Aug 30 10:09:37 2023 +0200 @@ -42,6 +42,7 @@ #include #include +#include // The "dl_iterate_phdr()" function (to walk through shared libraries) // is not available on Microsoft Windows and Apple OS X @@ -283,6 +284,8 @@ static bool pythonEnabled_ = false; static std::string userScriptName_; static std::vector globalFunctions_; +static boost::thread displayMemoryUsageThread_; +static bool displayMemoryUsageStopping_ = false; static void InstallClasses(PyObject* module) @@ -461,6 +464,27 @@ #endif +static void DisplayMemoryUsageThread() +{ + { + PythonLock lock; + lock.ExecuteCommand("import tracemalloc"); + lock.ExecuteCommand("tracemalloc.start()"); + } + + while (!displayMemoryUsageStopping_) + { + { + PythonLock lock; + lock.ExecuteCommand("print('Python memory usage: %0.03fMB' % " + "(tracemalloc.get_traced_memory() [0] / (1024.0 * 1024.0)))"); + } + + boost::this_thread::sleep(boost::posix_time::seconds(1)); + } +} + + extern "C" { ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* c) @@ -490,16 +514,18 @@ * Detection of the user script **/ - OrthancPlugins::OrthancConfiguration config; + OrthancPlugins::OrthancConfiguration globalConfig; - static const char* const OPTION = "PythonScript"; - + OrthancPlugins::OrthancConfiguration pythonConfig; + globalConfig.GetSection(pythonConfig, "Python"); + std::string script; - if (!config.LookupStringValue(script, OPTION)) + if (!globalConfig.LookupStringValue(script, "PythonScript") && + !pythonConfig.LookupStringValue(script, "Path")) { pythonEnabled_ = false; - OrthancPlugins::LogWarning("The option \"" + std::string(OPTION) + "\" is not provided: " + + OrthancPlugins::LogWarning("Options \"PythonScript\" and \"Python.Path\" are not provided: " "Python scripting is disabled"); } else @@ -540,16 +566,22 @@ * Initialization of Python **/ + const bool isVerbose = (globalConfig.GetBooleanValue("PythonVerbose", false) || + pythonConfig.GetBooleanValue("Verbose", false)); + #if HAS_DL_ITERATE == 1 dl_iterate_phdr(ForceImportCallback, NULL); #endif SetupGlobalFunctions(); - PythonLock::GlobalInitialize("orthanc", "OrthancException", - GetGlobalFunctions, InstallClasses, - config.GetBooleanValue("PythonVerbose", false)); + PythonLock::GlobalInitialize("orthanc", "OrthancException", GetGlobalFunctions, InstallClasses, isVerbose); PythonLock::AddSysPath(userScriptDirectory.string()); + if (pythonConfig.GetBooleanValue("DisplayMemoryUsage", false)) + { + displayMemoryUsageThread_ = boost::thread(DisplayMemoryUsageThread); + } + /** * Force loading the declarations in the user script @@ -592,6 +624,13 @@ FinalizeOnStoredInstanceCallback(); FinalizeIncomingHttpRequestFilter(); FinalizeDicomScpCallbacks(); + + displayMemoryUsageStopping_ = true; + + if (displayMemoryUsageThread_.joinable()) + { + displayMemoryUsageThread_.join(); + } PythonLock::GlobalFinalize(); }