Skip to content

Conversation

@requilence
Copy link
Contributor

@requilence requilence commented Jan 9, 2026

PR Description

TL;DR

Problem: When a user was kicked from a space (by another participant), the cleanup only removed ACL indexes via cleanACLIndexes() but left the space database files on disk. The space data was never fully removed.

Solution: Introduce proper space index lifecycle management tied to space mode transitions:

  • OnSpaceModeChange hook triggers CloseSpaceIndex() when space enters Offloading mode
  • DeleteSpaceIndex() permanently deletes the database files from filesystem and marks the proxy as deactivated

Why storeProxy: The proxy pattern was needed to safely handle the "deactivated but still referenced" state. After a space is deleted, existing code paths (like cross-space subscriptions or late callbacks) might still call SpaceIndex(deletedSpaceId). Without the proxy:

  • Direct access would panic on nil
  • Creating a new store would resurrect the deleted database via anystore.Open()

The proxy solves both: it returns sharedEmptyStore for deactivated spaces (safe empty results) and the removed flag prevents re-initialization even if Init() is called.


Key Concepts

State initialized removed Behavior
Uninitialized false false Empty results, can Init()
Initialized true false Real store operations
Closed false false Empty results, can re-Init()
Deactivated false true Empty results, Init() returns ErrSpaceRemoved

Flow

USER KICKED FROM SPACE:
1. Space mode → Offloading
2. OnSpaceModeChange() → CloseSpaceIndex()
3. storeProxy.initialized = false → delegates to sharedEmptyStore
4. DeleteSpaceIndex() → proxy.Deactivate() sets removed=true, deletes DB from disk

AFTER DELETION (safe access):
SpaceIndex(deletedId) → same proxy (in map) → removed=true → sharedEmptyStore → empty results, no DB recreation
Init() on deactivated proxy → returns ErrSpaceRemoved

Syncstatus optimization

  • Added AllLoadedSpaceIds() which only returns spaces in ModeLoading state
  • Excludes marketplace space and spaces being offloaded/deleted/joining
  • Reduces unnecessary sync status queries for inactive spaces

@requilence requilence changed the title Go 6331 objectstorespacestore on space leave 2 GO-6331 objectstorespacestore on space leave 2 Jan 9, 2026
@requilence requilence requested a review from deff7 January 9, 2026 11:10
@requilence requilence changed the title GO-6331 objectstorespacestore on space leave 2 GO-6331 objectstorestore remove on space leave Jan 9, 2026
}

func (p *storeProxy) SubscribeForAll(callback func(rec database.Record)) {
// Store the callback in the proxy so it survives until dsObjectStore is created.
Copy link
Member

Choose a reason for hiding this comment

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

why this is required? In order for subscriptions to work we need to re-run initial subscription query, not only register a callback

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.

2 participants