mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-03-13 17:20:01 +00:00
Adds opt-in process isolation for custom nodes using pyisolate's bwrap sandbox and JSON-RPC bridge. Each isolated node pack runs in its own child process with zero-copy tensor transfer via shared memory. Core infrastructure: - CLI flag --use-process-isolation to enable isolation - Host/child startup fencing via PYISOLATE_CHILD env var - Manifest-driven node discovery and extension loading - JSON-RPC bridge between host and child processes - Shared memory forensics for leak detection Proxy layer: - ModelPatcher, CLIP, VAE, and ModelSampling proxies - Host service proxies (folder_paths, model_management, progress, etc.) - Proxy base with automatic method forwarding Execution integration: - Extension wrapper with V3 hidden param mapping - Runtime helpers for isolated node execution - Host policy for node isolation decisions - Fenced sampler device handling and model ejection parity Serializers for cross-process data transfer: - File3D (GLB), PLY (structured + gaussian), NPZ (streaming frames), VIDEO (VideoFromFile + VideoFromComponents) serializers - data_type flag in SerializerRegistry for type-aware dispatch - Isolated get_temp_directory() fence New core save nodes: - SavePLY and SaveNPZ with comfytype registrations (Ply, Npz) DynamicVRAM compatibility: - comfy-aimdo early init gated by isolation fence Tests: - Integration and policy tests for isolation lifecycle - Manifest loader, host policy, proxy, and adapter unit tests Depends on: pyisolate >= 0.9.2
41 lines
1.3 KiB
Python
41 lines
1.3 KiB
Python
import os
|
|
|
|
import folder_paths
|
|
from comfy_api.latest import io
|
|
from comfy_api.latest._util.npz_types import NPZ
|
|
|
|
|
|
class SaveNPZ(io.ComfyNode):
|
|
@classmethod
|
|
def define_schema(cls):
|
|
return io.Schema(
|
|
node_id="SaveNPZ",
|
|
display_name="Save NPZ",
|
|
category="3d",
|
|
is_output_node=True,
|
|
inputs=[
|
|
io.Npz.Input("npz"),
|
|
io.String.Input("filename_prefix", default="da3_streaming/ComfyUI"),
|
|
],
|
|
)
|
|
|
|
@classmethod
|
|
def execute(cls, npz: NPZ, filename_prefix: str) -> io.NodeOutput:
|
|
full_output_folder, filename, counter, subfolder, _ = folder_paths.get_save_image_path(
|
|
filename_prefix, folder_paths.get_output_directory()
|
|
)
|
|
batch_dir = os.path.join(full_output_folder, f"{filename}_{counter:05}")
|
|
os.makedirs(batch_dir, exist_ok=True)
|
|
filenames = []
|
|
for i, frame_bytes in enumerate(npz.frames):
|
|
f = f"frame_{i:06d}.npz"
|
|
with open(os.path.join(batch_dir, f), "wb") as fh:
|
|
fh.write(frame_bytes)
|
|
filenames.append(f)
|
|
return io.NodeOutput(ui={"npz_files": [{"folder": os.path.join(subfolder, f"{filename}_{counter:05}"), "count": len(filenames), "type": "output"}]})
|
|
|
|
|
|
NODE_CLASS_MAPPINGS = {
|
|
"SaveNPZ": SaveNPZ,
|
|
}
|