diff --git a/jupyter_resource_usage/api.py b/jupyter_resource_usage/api.py index 22e3ae6..2c0a083 100644 --- a/jupyter_resource_usage/api.py +++ b/jupyter_resource_usage/api.py @@ -46,6 +46,8 @@ async def get(self): except (psutil.NoSuchProcess, psutil.AccessDenied) as e: pass + available = psutil.virtual_memory().available + if callable(config.mem_limit): mem_limit = config.mem_limit(rss=rss, pss=pss) else: # mem_limit is an Int @@ -58,6 +60,7 @@ async def get(self): ) metrics = {"rss": rss, "limits": limits} + metrics["mem_avail"] = available if pss is not None: metrics["pss"] = pss diff --git a/jupyter_resource_usage/config.py b/jupyter_resource_usage/config.py index 4a86c12..424648e 100644 --- a/jupyter_resource_usage/config.py +++ b/jupyter_resource_usage/config.py @@ -54,7 +54,10 @@ class ResourceUseDisplay(Configurable): system_memory_metrics = List( trait=PSUtilMetric(), - default_value=[{"name": "virtual_memory", "attribute": "total"}], + default_value=[ + {"name": "virtual_memory", "attribute": "total"}, + {"name": "virtual_memory", "attribute": "available"} + ], ) process_cpu_metrics = List( diff --git a/packages/labextension/src/model.ts b/packages/labextension/src/model.ts index 042d758..dc94525 100644 --- a/packages/labextension/src/model.ts +++ b/packages/labextension/src/model.ts @@ -254,9 +254,25 @@ export namespace ResourceUsage { this._memoryAvailable = numBytes !== undefined; this._currentMemory = currentMemory; this._memUnits = memUnits; - this._memoryLimit = memoryLimit - ? memoryLimit / MEMORY_UNIT_LIMITS[memUnits] + +// Use mem_avail if the host exposes it. + const hostAvailBytes = value.mem_avail ?? null ; + let minMemAvailable = null; + let hostMaxBytes = hostAvailBytes ? ( hostAvailBytes + numBytes ) : null; + + if ( memoryLimit && hostMaxBytes ) { minMemAvailable = Math.min(hostMaxBytes,memoryLimit); } + else if ( hostMaxBytes ) { minMemAvailable = hostMaxBytes } + else if ( memoryLimit ) { minMemAvailable = memoryLimit } + else if ( hostAvailBytes ) { minMemAvailable = hostAvailBytes + numBytes; } + + this._memoryLimit = minMemAvailable + ? minMemAvailable / MEMORY_UNIT_LIMITS[memUnits] : null; + +// this._memoryLimit = memoryLimit +// ? memoryLimit / MEMORY_UNIT_LIMITS[memUnits] +// : null; + const memoryPercent = this.memoryLimit ? Math.min(this._currentMemory / this.memoryLimit, 1) : 0; @@ -373,6 +389,7 @@ namespace Private { export interface IMetricRequestResult { rss: number; pss?: number; + mem_avail?: number; cpu_percent?: number; cpu_count?: number; disk_total?: number;