Files
c-relay-pg/plans/profile_fetcher_plan.md
T
Laan Tungir ca7a4b6722 v2.1.36 - Unified relay table, caching/backfill separation, inbox defaults, profile gating, and UI fixes
- Added caching_relays unified table with live_enabled/backfill_enabled columns
- Separated --reset-backfill from --start-caching as independent flags
- Removed redundant caching_enabled master setting; daemon derives from live/backfill
- Set caching_inbox_enabled=true by default; removed Inbox toggle from Backfill page
- Set caching_live_strategy=cache_all by default
- Fixed outbox relay discovery to store ALL discovered relays, not just covering set
- Added store_kind_0_information config (default: true) to gate profile sync trigger
- Regenerated pg_schema.h from pg_schema.sql to include caching_relays table
- Fixed process toggle button styling to match monochrome aesthetic
- Fixed radio button styling to match black/white/red theme
- Simplified Backfill page: removed Service Status and Inbox Status sections
- Backfill status now respects config setting, not just daemon state
- Admin config API now bumps caching_config_generation for caching-related changes
- make_and_restart_relay.sh now resets PostgreSQL schema on fresh restart
2026-08-03 19:37:09 -04:00

2.8 KiB

Profile Fetcher — Main Relay Implementation Plan

Problem

Kind-0 (profile metadata) events are currently only fetched by the external caching_relay daemon. Profiles should be populated independently of the caching service, controlled by a simple config setting in the main relay.

Design

A lightweight background thread in the main relay that periodically queries kind-0 events for pubkeys that are missing from the profiles table.

flowchart LR
    A[profile_fetch_enabled=true] --> B[profile_fetcher_init]
    B --> C[Worker thread starts]
    C --> D[Every 60s: query pubkeys<br/>missing from profiles]
    D --> E[Batch of 100 pubkeys]
    E --> F[nostr_relay_pool query<br/>kind-0 from upstream]
    F --> G[ingest_event for each result]
    G --> H[trg_events_sync_profile trigger]
    H --> I[profiles table populated]

Files to Create

src/profile_fetcher.h

  • int profile_fetcher_init(void); — start the worker thread
  • void profile_fetcher_shutdown(void); — stop the thread
  • int profile_fetcher_is_running(void); — check if thread is active

src/profile_fetcher.c

  • Worker thread function that loops:
    1. Sleep 60 seconds
    2. Query: SELECT DISTINCT pubkey FROM events WHERE kind = 0 AND pubkey NOT IN (SELECT pubkey FROM profiles) LIMIT 100
    3. If empty, sleep and retry
    4. If pubkeys found, query kind-0 from upstream relay pool
    5. Feed returned events through ingest_event()
    6. Loop
  • Uses the relay's existing nostr_relay_pool for upstream queries
  • Thread-safe shutdown via atomic flag

Files to Modify

src/default_config_event.h

Add:

{"profile_fetch_enabled", "false"},  // Enable background profile metadata fetcher
{"profile_fetch_interval_seconds", "60"},  // Poll interval
{"profile_fetch_batch_size", "100"},  // Pubkeys per batch

src/config.c

  • Add validation for profile_fetch_enabled (boolean)
  • Add validation for profile_fetch_interval_seconds (positive int)
  • Add validation for profile_fetch_batch_size (positive int, 1-500)
  • Add to is_boolean_config_key() and is_integer_config_key() lists

src/main.c

  • After caching_inbox_poller_init(), call profile_fetcher_init()
  • Before caching_inbox_poller_shutdown(), call profile_fetcher_shutdown()

admin/api/config.php

  • Add profile_fetch_enabled to the config-generation bump list

Makefile

  • Add src/profile_fetcher.c to MAIN_SRC

Config Page

No new UI section needed — profile_fetch_enabled appears in the general Configuration page alongside other boolean settings. The user can toggle it there.

Dependencies

  • Uses the existing nostr_relay_pool (already initialized in main.c)
  • Uses the existing ingest_event() pipeline
  • Uses the existing profiles table and trg_events_sync_profile trigger
  • PostgreSQL-only (no-op for SQLite builds)