Skip to content

[v3] Perf(cnr): Optimize ComfyRegistry startup loading using incremental caching#3031

Open
craftingmod wants to merge 13 commits into
Comfy-Org:mainfrom
craftingmod:fix-cache-dir
Open

[v3] Perf(cnr): Optimize ComfyRegistry startup loading using incremental caching#3031
craftingmod wants to merge 13 commits into
Comfy-Org:mainfrom
craftingmod:fix-cache-dir

Conversation

@craftingmod

@craftingmod craftingmod commented Jun 29, 2026

Copy link
Copy Markdown

Summary

This PR significantly optimizes the startup and reload latency of the ComfyRegistry (CNR) node loader.
By replacing the full-fetch mechanism with a server-time-based incremental sync (delta sync), it reduces the data fetched at boot time from the entire registry database (currently 4,600+ nodes across 150+ pages) to only new or updated nodes since the last run.
This reduces the ComfyRegistry sync time on startup from ~50 seconds to less than 1 second under normal conditions.

Problem

Previously, cnr_utils.py performed a full sync of the entire registry database page-by-page (limit=30, hitting the endpoint 150+ times with a time.sleep(0.5) gap) whenever it synced or when the daily cache expired. As the number of custom nodes in the registry continues to grow, this startup latency has organically degraded to over 50 seconds, creating a noticeable delay during ComfyUI boot. (Even if it runs on background, fetching process costs network request on api.comfyui.org and not avoidable until finish.)

How to implemented

https://docs.comfy.org/api-reference/registry/retrieves-a-list-of-nodes#parameter-timestamp

Integrated the timestamp parameter supported by GET https://api.comfy.org/nodes to request only nodes created or updated after the cached timestamp.

Related issues

Addresses the performance issues mentioned in #2229 #1950 #1629.

Why PR

Watching every fetch of ComfyUI Nodes is painful while coding custom_nodes...
And after 1.5 years of issue is created, v4 isn't even closed to release on main branch.

@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Refactors CNR fetching to use sync_mode, adds runtime metadata cache validation, paginated incremental fetching, and generalized file-age checks. The reload call site is updated, and logging replaces print-based error reporting.

Changes

CNR Fetch Refactor and Cache Generalization

Layer / File(s) Summary
Generalized file-age and cache-state helpers
glob/manager_util.py
Adds is_file_created_within_days(file_path, days) with a None-always-valid case, rewires is_file_created_within_one_day to delegate to it, and extends get_cache_state with an expired_days parameter.
Public API signature and call-site update
glob/cnr_utils.py, glob/manager_core.py
Changes get_cnr_data and _get_cnr_data to accept sync_mode and legacy kwargs, updates UnifiedManager.reload() to pass sync_mode=cache_mode, and switches timeout and .cnr-id failure reporting to logging.
Runtime metadata helpers and cache validation
glob/cnr_utils.py
Adds ComfyUI version and form-factor helpers, then uses stored metadata to validate cached CNR data against the current runtime.
Paginated incremental fetch and cache save
glob/cnr_utils.py
Implements page-by-page fetching with timestamp filtering and throttling, computes cache timestamps from fetched nodes, saves metadata with the cache, and falls back to cached nodes or [] on fetch failure.
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@glob/cnr_utils.py`:
- Around line 140-142: The query string in the nodes request is built via raw
interpolation, so dynamic values like comfyui_ver and timestamp_filter can be
sent incorrectly when they contain reserved characters. Update the sub_uri
construction in the related fetch logic to build the query via urlencode (or
equivalent parameter encoding) for page, limit, comfyui_version, form_factor,
and timestamp, keeping the existing request path and ensuring the encoded values
come from the same variables used in the current block.
- Line 157: The fetch_all coroutine is using a blocking sleep inside async code,
which pauses the event loop between pages. Update the sleep call in fetch_all to
use asyncio’s non-blocking sleep instead of time.sleep, and make sure the
function already imports and uses asyncio appropriately so other startup/reload
tasks can continue running.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e8894998-b981-4fbb-b21c-eedc0b4e3c7d

📥 Commits

Reviewing files that changed from the base of the PR and between 94a3ae8 and 62fd585.

📒 Files selected for processing (3)
  • glob/cnr_utils.py
  • glob/manager_core.py
  • glob/manager_util.py

Comment thread glob/cnr_utils.py Outdated
Comment thread glob/cnr_utils.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
glob/cnr_utils.py (1)

124-133: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Return [] here, not {}. manager_core.reload iterates this as a list of node dicts, so an empty dict turns into string keys and can break reload on a cache miss.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@glob/cnr_utils.py` around lines 124 - 133, The cache-miss branch in
normalized_mode == 'cache' currently returns an empty dict instead of the list
shape expected by manager_core.reload. Update the logic in the cache handling
path near get_cache_state so that the dont_wait/no cached_data case returns an
empty list, matching the nodes list returned by cached_data.get('nodes', []).
Keep the behavior consistent across this branch and the surrounding cache
loading flow in cnr_utils.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@glob/cnr_utils.py`:
- Around line 124-133: The cache-miss branch in normalized_mode == 'cache'
currently returns an empty dict instead of the list shape expected by
manager_core.reload. Update the logic in the cache handling path near
get_cache_state so that the dont_wait/no cached_data case returns an empty list,
matching the nodes list returned by cached_data.get('nodes', []). Keep the
behavior consistent across this branch and the surrounding cache loading flow in
cnr_utils.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 182793d0-2f69-4e42-9184-da6b5bb7646d

📥 Commits

Reviewing files that changed from the base of the PR and between 62fd585 and 9a0b2c4.

📒 Files selected for processing (1)
  • glob/cnr_utils.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
glob/cnr_utils.py (2)

124-133: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Clear is_cache_loading before every cache-mode return.

Line 125 sets the global flag before the dont_wait and fresh-cache fast paths, but those returns happen before the finally at Line 206. After any fast return, the manager can look permanently “loading” — a sticky little imp.

Proposed fix
     if normalized_mode == 'cache':
-        is_cache_loading = True
-
         if dont_wait:
             if cached_data is not None:
                 return cached_data.get('nodes', [])
             return []

         if cached_data is not None and manager_util.get_cache_state(uri, expired_days=1) == 'cached':
             return cached_data.get('nodes', [])

+        is_cache_loading = True
+
     async def fetch_all(timestamp_filter, existing_nodes):

Also applies to: 206-208

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@glob/cnr_utils.py` around lines 124 - 133, The cache-mode fast paths in
cnr_utils should clear the global is_cache_loading flag before returning, since
the early returns in the normalized_mode == 'cache' branch bypass the later
finally cleanup. Update the cache handling around the dont_wait and fresh
cached_data checks so the flag is reset before each return, using the existing
is_cache_loading and manager_util.get_cache_state flow to locate the fix.

175-191: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Do not advance incremental cache timestamps with the local clock.

When no node timestamp is available, Line 191 persists datetime.now(...) as last_updated. If the client clock is ahead of the registry server, the next timestamp query can skip updates created before that local time. Keep the previous timestamp, or leave it unset, until a node/server timestamp is observed.

Proposed fix
-        from datetime import datetime, timezone, timedelta
+        from datetime import datetime, timedelta
         json_obj = await fetch_all(last_updated, full_nodes)
@@
         else:
-            new_timestamp = last_updated if last_updated else datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
+            new_timestamp = last_updated

Also applies to: 193-199

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@glob/cnr_utils.py` around lines 175 - 191, The cache timestamp fallback in
the fetch/update flow should not use the local clock when no node timestamp is
available. Update the logic around fetch_all, get_node_timestamp, and the
new_timestamp assignment so it preserves last_updated (or leaves it unset) until
a registry-derived timestamp is seen, instead of calling datetime.now(...). Also
keep the existing max_timestamp adjustment path intact for observed node
timestamps.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@glob/cnr_utils.py`:
- Around line 124-133: The cache-mode fast paths in cnr_utils should clear the
global is_cache_loading flag before returning, since the early returns in the
normalized_mode == 'cache' branch bypass the later finally cleanup. Update the
cache handling around the dont_wait and fresh cached_data checks so the flag is
reset before each return, using the existing is_cache_loading and
manager_util.get_cache_state flow to locate the fix.
- Around line 175-191: The cache timestamp fallback in the fetch/update flow
should not use the local clock when no node timestamp is available. Update the
logic around fetch_all, get_node_timestamp, and the new_timestamp assignment so
it preserves last_updated (or leaves it unset) until a registry-derived
timestamp is seen, instead of calling datetime.now(...). Also keep the existing
max_timestamp adjustment path intact for observed node timestamps.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f26781a7-7a0b-42e1-bdc8-aab687bae516

📥 Commits

Reviewing files that changed from the base of the PR and between 9a0b2c4 and ec2023a.

📒 Files selected for processing (1)
  • glob/cnr_utils.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
glob/cnr_utils.py (1)

66-72: 🚀 Performance & Scalability | 🟠 Major | 🏗️ Heavy lift

Use the server update timestamp for the incremental cursor.

This helper only returns creation timestamps, but the sync fetches nodes created or updated since last_updated. Updates to existing nodes whose creation time predates the cursor can be re-fetched forever, keeping startup sync slower than intended—an impish cache loop. Prefer the API’s updated timestamp field, falling back to creation time only when absent.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@glob/cnr_utils.py` around lines 66 - 72, The get_node_timestamp helper is
using only creation timestamps, which breaks the incremental cursor for updated
nodes. Update get_node_timestamp to prefer the server’s updated timestamp from
latest_version when available, and only fall back to createdAt/created_at if the
update time is missing. Make sure the sync path that relies on this helper
continues to use the same function so the cursor advances on both created and
updated nodes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@glob/cnr_utils.py`:
- Around line 66-72: The get_node_timestamp helper is using only creation
timestamps, which breaks the incremental cursor for updated nodes. Update
get_node_timestamp to prefer the server’s updated timestamp from latest_version
when available, and only fall back to createdAt/created_at if the update time is
missing. Make sure the sync path that relies on this helper continues to use the
same function so the cursor advances on both created and updated nodes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9917baac-312e-453f-b359-fea95587f59f

📥 Commits

Reviewing files that changed from the base of the PR and between ec2023a and 9a827e4.

📒 Files selected for processing (1)
  • glob/cnr_utils.py

@craftingmod

This comment was marked as resolved.

@craftingmod

Copy link
Copy Markdown
Author

I understand that v3 is in maintenance mode and no longer accepting new feature updates.
But why not applying easy fix in v3 instead of waiting v4 while being pressed for time?

 * for github star, download counts.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
glob/cnr_utils.py (1)

29-31: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Let asyncio.TimeoutError bubble past _get_cnr_data.
glob/cnr_utils.py:223 catches the timeout raised by asyncio.wait_for, so get_cnr_data() never reaches its cache fallback. In force mode, that turns a timeout into [] instead of falling back to cache — a tiny timeout gremlin.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@glob/cnr_utils.py` around lines 29 - 31, The timeout handling in
_get_cnr_data is swallowing asyncio.TimeoutError too early, preventing
get_cnr_data from reaching its cache fallback in force mode. Remove the local
catch around the fetch path in _get_cnr_data (or re-raise the timeout) so the
asyncio.wait_for timeout can bubble up to get_cnr_data, where the existing cache
fallback logic should handle it.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@glob/cnr_utils.py`:
- Around line 29-31: The timeout handling in _get_cnr_data is swallowing
asyncio.TimeoutError too early, preventing get_cnr_data from reaching its cache
fallback in force mode. Remove the local catch around the fetch path in
_get_cnr_data (or re-raise the timeout) so the asyncio.wait_for timeout can
bubble up to get_cnr_data, where the existing cache fallback logic should handle
it.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 7c5ee4a6-e0c6-4c75-8142-cf3089116e46

📥 Commits

Reviewing files that changed from the base of the PR and between 9a827e4 and 5427efd.

📒 Files selected for processing (1)
  • glob/cnr_utils.py

 * Now correctly refresh cache if cache is created
 * Seperate cache update / cache created time
 * revert 7-day expiration logic
@craftingmod

This comment was marked as resolved.

@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
glob/cnr_utils.py (1)

141-145: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Don’t skip initial cache creation when dont_wait is true.

Line 141 returns before fetch_all() when there is no valid cache, so a fresh install or environment-invalidated cache returns [] and never creates the CNR cache from the default UnifiedManager.reload(..., dont_wait=True) path. That makes the registry vanish like an imp in a puff of smoke.

🐛 Proposed fix
-        if dont_wait:
+        if dont_wait and cached_data is not None:
             is_cache_loading = False
-            if cached_data is not None:
-                return cached_data.get('nodes', [])
-            return []
+            return cached_data.get('nodes', [])
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@glob/cnr_utils.py` around lines 141 - 145, The early return in the dont_wait
branch of fetch_all is skipping initial cache population when cached_data is
missing, so a fresh or invalidated install never builds the CNR cache. Update
fetch_all so dont_wait still triggers the initial cache creation path and only
returns immediately when an existing cache is available; use the existing
fetch_all and UnifiedManager.reload flow to preserve async behavior while
ensuring the cache is created at least once.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@glob/cnr_utils.py`:
- Around line 141-145: The early return in the dont_wait branch of fetch_all is
skipping initial cache population when cached_data is missing, so a fresh or
invalidated install never builds the CNR cache. Update fetch_all so dont_wait
still triggers the initial cache creation path and only returns immediately when
an existing cache is available; use the existing fetch_all and
UnifiedManager.reload flow to preserve async behavior while ensuring the cache
is created at least once.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2169d938-13d5-4d7c-a52d-a74432429b8e

📥 Commits

Reviewing files that changed from the base of the PR and between 9a827e4 and 5513395.

📒 Files selected for processing (1)
  • glob/cnr_utils.py

@craftingmod

This comment was marked as resolved.

@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown
✅ Action performed

Reviews resumed.

Comment thread glob/cnr_utils.py
lock = asyncio.Lock()

is_cache_loading = False
force_refresh_days = 30

@craftingmod craftingmod Jun 29, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Full-refresh in 30 days should be enough.
And if 1day is what you want, you can use 1 as everyday invalidate cache.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
glob/cnr_utils.py (1)

30-32: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Make the timeout fallback truly local-only.

Line 32 retries with sync_mode='cache', but Lines 158-164 only return early when cached_data exists; cache misses still fall through to the remote fetch path. That can turn one timeout into a second network encore—the imp gets two drums. Use local fallback and stop before fetching when no local cache is available.

Proposed fix
     except asyncio.TimeoutError:
         logging.error(f"[ComfyUI-Manager] A timeout occurred during the fetch process from ComfyRegistry.")
-        return await _get_cnr_data(sync_mode='cache', dont_wait=True)  # timeout fallback
+        return await _get_cnr_data(sync_mode='local', dont_wait=True)  # timeout fallback
@@
         if cached_data is not None and (sync_mode == 'local' or not is_cache_expired):
             is_cache_loading = False
             return cached_data.get('nodes', [])
+
+        if sync_mode == 'local':
+            is_cache_loading = False
+            return []

Also applies to: 154-166

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@glob/cnr_utils.py` around lines 30 - 32, The timeout fallback in
_get_cnr_data is still able to hit the network because the retry uses
sync_mode='cache', which only short-circuits when cached_data exists. Update the
asyncio.TimeoutError handler to use the truly local fallback mode and ensure the
local-cache path in _get_cnr_data returns immediately before any remote fetch
when no cached_data is available. Keep the fix centered on _get_cnr_data and its
cache handling branch so the timeout path remains offline-only.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@glob/cnr_utils.py`:
- Around line 30-32: The timeout fallback in _get_cnr_data is still able to hit
the network because the retry uses sync_mode='cache', which only short-circuits
when cached_data exists. Update the asyncio.TimeoutError handler to use the
truly local fallback mode and ensure the local-cache path in _get_cnr_data
returns immediately before any remote fetch when no cached_data is available.
Keep the fix centered on _get_cnr_data and its cache handling branch so the
timeout path remains offline-only.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: cdfdec63-d9d5-40ec-921f-93a880ea6759

📥 Commits

Reviewing files that changed from the base of the PR and between 5513395 and b59eb64.

📒 Files selected for processing (1)
  • glob/cnr_utils.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
glob/cnr_utils.py (1)

215-224: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Parse timestamps before choosing the cursor. max() over raw strings is only safe if every timestamp is normalized to the same precision; these API values already vary in fractional digits, so a newer value can sort behind an older one. Tiny fix, big gain—don’t let the cursor play imp.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@glob/cnr_utils.py` around lines 215 - 224, The cursor selection in the
timestamp logic is using max() on raw timestamp strings, which can pick the
wrong value when API timestamps have different fractional-second precision.
Update the timestamp handling around get_node_timestamp and the max_timestamp
calculation to parse each timestamp into a datetime before comparing, then
choose the latest parsed value and apply the existing 10-second backoff before
formatting the cursor string.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@glob/cnr_utils.py`:
- Around line 215-224: The cursor selection in the timestamp logic is using
max() on raw timestamp strings, which can pick the wrong value when API
timestamps have different fractional-second precision. Update the timestamp
handling around get_node_timestamp and the max_timestamp calculation to parse
each timestamp into a datetime before comparing, then choose the latest parsed
value and apply the existing 10-second backoff before formatting the cursor
string.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2ab97ec8-45fb-4fcf-9195-c9d245c2ed58

📥 Commits

Reviewing files that changed from the base of the PR and between b59eb64 and 4da6b80.

📒 Files selected for processing (1)
  • glob/cnr_utils.py

@craftingmod

This comment was marked as resolved.

@craftingmod craftingmod changed the title Perf(cnr): Optimize ComfyRegistry startup loading using incremental caching [v3] Perf(cnr): Optimize ComfyRegistry startup loading using incremental caching Jul 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant