Remove caching feature

This commit is contained in:
Alexis Rolland 2026-06-17 10:03:48 +08:00
parent 17418ab5bf
commit 9c47058b49
6 changed files with 4 additions and 40 deletions

View File

@ -1600,8 +1600,6 @@ class Schema:
"""Optional client-evaluated pricing badge declaration for this node.""" """Optional client-evaluated pricing badge declaration for this node."""
not_idempotent: bool=False not_idempotent: bool=False
"""Flags a node as not idempotent; when True, the node will run and not reuse the cached outputs when identical inputs are provided on a different node in the graph.""" """Flags a node as not idempotent; when True, the node will run and not reuse the cached outputs when identical inputs are provided on a different node in the graph."""
cache_no_cascade: bool=False
"""When True, changes to this node's widget inputs re-run this node but do not invalidate the caches of downstream nodes. Use for passthrough nodes whose widget inputs only affect side effects (e.g. a save node's filename), not the data passed to its outputs."""
enable_expand: bool=False enable_expand: bool=False
"""Flags a node as expandable, allowing NodeOutput to include 'expand' property.""" """Flags a node as expandable, allowing NodeOutput to include 'expand' property."""
accept_all_inputs: bool=False accept_all_inputs: bool=False
@ -2067,14 +2065,6 @@ class _ComfyNodeBaseInternal(_ComfyNodeInternal):
cls.GET_SCHEMA() cls.GET_SCHEMA()
return cls._NOT_IDEMPOTENT return cls._NOT_IDEMPOTENT
_CACHE_NO_CASCADE = None
@final
@classproperty
def CACHE_NO_CASCADE(cls): # noqa
if cls._CACHE_NO_CASCADE is None:
cls.GET_SCHEMA()
return cls._CACHE_NO_CASCADE
_ACCEPT_ALL_INPUTS = None _ACCEPT_ALL_INPUTS = None
@final @final
@classproperty @classproperty
@ -2125,8 +2115,6 @@ class _ComfyNodeBaseInternal(_ComfyNodeInternal):
cls._INPUT_IS_LIST = schema.is_input_list cls._INPUT_IS_LIST = schema.is_input_list
if cls._NOT_IDEMPOTENT is None: if cls._NOT_IDEMPOTENT is None:
cls._NOT_IDEMPOTENT = schema.not_idempotent cls._NOT_IDEMPOTENT = schema.not_idempotent
if cls._CACHE_NO_CASCADE is None:
cls._CACHE_NO_CASCADE = schema.cache_no_cascade
if cls._ACCEPT_ALL_INPUTS is None: if cls._ACCEPT_ALL_INPUTS is None:
cls._ACCEPT_ALL_INPUTS = schema.accept_all_inputs cls._ACCEPT_ALL_INPUTS = schema.accept_all_inputs

View File

@ -14,7 +14,6 @@ import nodes
from comfy_execution.graph_utils import is_link from comfy_execution.graph_utils import is_link
NODE_CLASS_CONTAINS_UNIQUE_ID: Dict[str, bool] = {} NODE_CLASS_CONTAINS_UNIQUE_ID: Dict[str, bool] = {}
NODE_CLASS_CACHE_NO_CASCADE: Dict[str, bool] = {}
def include_unique_id_in_input(class_type: str) -> bool: def include_unique_id_in_input(class_type: str) -> bool:
@ -24,16 +23,6 @@ def include_unique_id_in_input(class_type: str) -> bool:
NODE_CLASS_CONTAINS_UNIQUE_ID[class_type] = "UNIQUE_ID" in class_def.INPUT_TYPES().get("hidden", {}).values() NODE_CLASS_CONTAINS_UNIQUE_ID[class_type] = "UNIQUE_ID" in class_def.INPUT_TYPES().get("hidden", {}).values()
return NODE_CLASS_CONTAINS_UNIQUE_ID[class_type] return NODE_CLASS_CONTAINS_UNIQUE_ID[class_type]
def is_cache_no_cascade(class_type: str) -> bool:
"""Whether changes to this node's widget inputs should not invalidate downstream caches."""
if class_type in NODE_CLASS_CACHE_NO_CASCADE:
return NODE_CLASS_CACHE_NO_CASCADE[class_type]
class_def = nodes.NODE_CLASS_MAPPINGS[class_type]
NODE_CLASS_CACHE_NO_CASCADE[class_type] = bool(getattr(class_def, "CACHE_NO_CASCADE", False))
return NODE_CLASS_CACHE_NO_CASCADE[class_type]
class CacheKeySet(ABC): class CacheKeySet(ABC):
def __init__(self, dynprompt, node_ids, is_changed_cache): def __init__(self, dynprompt, node_ids, is_changed_cache):
self.keys = {} self.keys = {}
@ -112,12 +101,12 @@ class CacheKeySetInputSignature(CacheKeySet):
async def get_node_signature(self, dynprompt, node_id): async def get_node_signature(self, dynprompt, node_id):
signature = [] signature = []
ancestors, order_mapping = self.get_ordered_ancestry(dynprompt, node_id) ancestors, order_mapping = self.get_ordered_ancestry(dynprompt, node_id)
signature.append(await self.get_immediate_node_signature(dynprompt, node_id, order_mapping, as_ancestor=False)) signature.append(await self.get_immediate_node_signature(dynprompt, node_id, order_mapping))
for ancestor_id in ancestors: for ancestor_id in ancestors:
signature.append(await self.get_immediate_node_signature(dynprompt, ancestor_id, order_mapping, as_ancestor=True)) signature.append(await self.get_immediate_node_signature(dynprompt, ancestor_id, order_mapping))
return to_hashable(signature) return to_hashable(signature)
async def get_immediate_node_signature(self, dynprompt, node_id, ancestor_order_mapping, as_ancestor=False): async def get_immediate_node_signature(self, dynprompt, node_id, ancestor_order_mapping):
if not dynprompt.has_node(node_id): if not dynprompt.has_node(node_id):
# This node doesn't exist -- we can't cache it. # This node doesn't exist -- we can't cache it.
return [float("NaN")] return [float("NaN")]
@ -128,13 +117,12 @@ class CacheKeySetInputSignature(CacheKeySet):
if self.include_node_id_in_input() or (hasattr(class_def, "NOT_IDEMPOTENT") and class_def.NOT_IDEMPOTENT) or include_unique_id_in_input(class_type): if self.include_node_id_in_input() or (hasattr(class_def, "NOT_IDEMPOTENT") and class_def.NOT_IDEMPOTENT) or include_unique_id_in_input(class_type):
signature.append(node_id) signature.append(node_id)
inputs = node["inputs"] inputs = node["inputs"]
skip_widgets = as_ancestor and is_cache_no_cascade(class_type)
for key in sorted(inputs.keys()): for key in sorted(inputs.keys()):
if is_link(inputs[key]): if is_link(inputs[key]):
(ancestor_id, ancestor_socket) = inputs[key] (ancestor_id, ancestor_socket) = inputs[key]
ancestor_index = ancestor_order_mapping[ancestor_id] ancestor_index = ancestor_order_mapping[ancestor_id]
signature.append((key,("ANCESTOR", ancestor_index, ancestor_socket))) signature.append((key,("ANCESTOR", ancestor_index, ancestor_socket)))
elif not skip_widgets: else:
signature.append((key, inputs[key])) signature.append((key, inputs[key]))
return signature return signature

View File

@ -168,7 +168,6 @@ class SaveAudio(IO.ComfyNode):
hidden=[IO.Hidden.prompt, IO.Hidden.extra_pnginfo], hidden=[IO.Hidden.prompt, IO.Hidden.extra_pnginfo],
is_deprecated=True, is_deprecated=True,
is_output_node=True, is_output_node=True,
cache_no_cascade=True,
outputs=[IO.Audio.Output("audio")] outputs=[IO.Audio.Output("audio")]
) )
@ -199,7 +198,6 @@ class SaveAudioMP3(IO.ComfyNode):
hidden=[IO.Hidden.prompt, IO.Hidden.extra_pnginfo], hidden=[IO.Hidden.prompt, IO.Hidden.extra_pnginfo],
is_deprecated=True, is_deprecated=True,
is_output_node=True, is_output_node=True,
cache_no_cascade=True,
outputs=[IO.Audio.Output("audio")] outputs=[IO.Audio.Output("audio")]
) )
@ -231,7 +229,6 @@ class SaveAudioOpus(IO.ComfyNode):
hidden=[IO.Hidden.prompt, IO.Hidden.extra_pnginfo], hidden=[IO.Hidden.prompt, IO.Hidden.extra_pnginfo],
is_deprecated=True, is_deprecated=True,
is_output_node=True, is_output_node=True,
cache_no_cascade=True,
outputs=[IO.Audio.Output("audio")] outputs=[IO.Audio.Output("audio")]
) )
@ -279,7 +276,6 @@ class SaveAudioAdvanced(IO.ComfyNode):
], ],
hidden=[IO.Hidden.prompt, IO.Hidden.extra_pnginfo], hidden=[IO.Hidden.prompt, IO.Hidden.extra_pnginfo],
is_output_node=True, is_output_node=True,
cache_no_cascade=True,
outputs=[IO.Audio.Output("audio")], outputs=[IO.Audio.Output("audio")],
) )

View File

@ -214,7 +214,6 @@ class SaveAnimatedWEBP(IO.ComfyNode):
], ],
hidden=[IO.Hidden.prompt, IO.Hidden.extra_pnginfo], hidden=[IO.Hidden.prompt, IO.Hidden.extra_pnginfo],
is_output_node=True, is_output_node=True,
cache_no_cascade=True,
outputs=[IO.Image.Output(display_name="images")] outputs=[IO.Image.Output(display_name="images")]
) )
@ -250,7 +249,6 @@ class SaveAnimatedPNG(IO.ComfyNode):
], ],
hidden=[IO.Hidden.prompt, IO.Hidden.extra_pnginfo], hidden=[IO.Hidden.prompt, IO.Hidden.extra_pnginfo],
is_output_node=True, is_output_node=True,
cache_no_cascade=True,
outputs=[IO.Image.Output(display_name="images")] outputs=[IO.Image.Output(display_name="images")]
) )
@ -515,7 +513,6 @@ class SaveSVGNode(IO.ComfyNode):
], ],
hidden=[IO.Hidden.prompt, IO.Hidden.extra_pnginfo], hidden=[IO.Hidden.prompt, IO.Hidden.extra_pnginfo],
is_output_node=True, is_output_node=True,
cache_no_cascade=True,
outputs=[IO.SVG.Output("svg")], outputs=[IO.SVG.Output("svg")],
) )
@ -1189,7 +1186,6 @@ class SaveImageAdvanced(IO.ComfyNode):
], ],
hidden=[IO.Hidden.prompt, IO.Hidden.extra_pnginfo], hidden=[IO.Hidden.prompt, IO.Hidden.extra_pnginfo],
is_output_node=True, is_output_node=True,
cache_no_cascade=True,
outputs=[IO.Image.Output(display_name="images")] outputs=[IO.Image.Output(display_name="images")]
) )

View File

@ -27,7 +27,6 @@ class SaveWEBM(io.ComfyNode):
], ],
hidden=[io.Hidden.prompt, io.Hidden.extra_pnginfo], hidden=[io.Hidden.prompt, io.Hidden.extra_pnginfo],
is_output_node=True, is_output_node=True,
cache_no_cascade=True,
outputs=[io.Image.Output(display_name="images")] outputs=[io.Image.Output(display_name="images")]
) )
@ -91,7 +90,6 @@ class SaveVideo(io.ComfyNode):
], ],
hidden=[io.Hidden.prompt, io.Hidden.extra_pnginfo], hidden=[io.Hidden.prompt, io.Hidden.extra_pnginfo],
is_output_node=True, is_output_node=True,
cache_no_cascade=True,
outputs=[io.Video.Output("video")], outputs=[io.Video.Output("video")],
) )

View File

@ -493,7 +493,6 @@ class SaveLatent:
FUNCTION = "save" FUNCTION = "save"
OUTPUT_NODE = True OUTPUT_NODE = True
CACHE_NO_CASCADE = True
CATEGORY = "experimental" CATEGORY = "experimental"
@ -1649,7 +1648,6 @@ class SaveImage:
FUNCTION = "save_images" FUNCTION = "save_images"
OUTPUT_NODE = True OUTPUT_NODE = True
CACHE_NO_CASCADE = True
CATEGORY = "image" CATEGORY = "image"
ESSENTIALS_CATEGORY = "Basics" ESSENTIALS_CATEGORY = "Basics"