Skip to content

Loading overlay race condition — multiple API calls fight over a single flag #656

Description

@codeGlaze

Problem

The loading spinner overlay uses a single boolean flag in app-db. When you navigate to a page like the character list, multiple subscriptions fire HTTP calls simultaneously (characters, folders, items, parties). Each one sets loading = true before its call and loading = false after.

When any of those calls returns a 401 (expired token, server restart, etc.), the app redirects to login — but other calls are still in flight. The result: the login page renders, then the loading overlay covers it. You're staring at a spinner on top of a login form.

Root cause

Data fetching lives inside reg-sub-raw go blocks. These fire as a side effect of rendering — the moment a component subscribes, the HTTP call launches. There's no coordination between them and no way to cancel in-flight requests when navigating away.

This means:

  • 4+ HTTP calls fire in parallel just to paint one page
  • Each independently toggles the same boolean loading flag
  • A 401 on one call redirects to login while others are still pending
  • The loading overlay gets stuck because the flag state is unpredictable

Current fix (hotfix branch)

Changed :loading from a boolean to a counter. true increments, false decrements, overlay shows when > 0. The :route-to-login event resets the counter to 0. This stops the overlay from getting stuck.

Proper fix (future)

Move data fetching out of subscriptions and into page lifecycle events:

  1. Each route dispatches a :page-entered event
  2. That event dispatches only the fetches that page needs
  3. Subscriptions become pure reads from app-db (no side effects)
  4. Loading state is managed per-resource or with a coordinated counter

This is a larger refactor but eliminates the whole class of "subscriptions firing HTTP calls at render time" bugs.

Affected files

  • src/cljs/orcpub/dnd/e5/subs.cljsreg-sub-raw handlers for characters, parties, folders
  • src/cljs/orcpub/dnd/e5/equipment_subs.cljsreg-sub-raw for custom items
  • src/cljs/orcpub/dnd/e5/events.cljs:set-loading handler, :route-to-login
  • src/cljs/orcpub/dnd/e5/views.cljs — loading overlay render check

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions