Skip to content

fix: namespace localStorage keys to prevent multi-instance contention - #8

Open
samanthataylor3 wants to merge 1 commit into
masterfrom
devin/1782231883-storage-namespace
Open

fix: namespace localStorage keys to prevent multi-instance contention#8
samanthataylor3 wants to merge 1 commit into
masterfrom
devin/1782231883-storage-namespace

Conversation

@samanthataylor3

@samanthataylor3 samanthataylor3 commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Closes #5

Describe your changes:

Multiple Open MCT instances running on the same host:port previously collided on bare localStorage keys (e.g. mct-recent-objects, notebook-storage, tcHistory). This PR introduces a centralized StorageManager utility that optionally prefixes all keys with a configurable namespace.

Architecture:

openmct.setStorageNamespace('instance-A');
// All subsequent storage calls produce keys like: "instance-A:mct-recent-objects"

Key changes:

  • src/utils/StorageManager.js — new utility: _prefixKey(key) returns namespace ? namespace:key : key
  • openmct.storage exposed on the MCT instance; openmct.setStorageNamespace(ns) API for configuration before start()
  • All 12+ localStorage call sites refactored to go through openmct.storage.{getItem,setItem,removeItem}
  • LocalStorageObjectProvider now accepts the StorageManager instance for its space key operations
  • Standalone singletons (StylesManager, notebook-storage) accept storage via setStorage() / setNotebookStorage() hooks called at plugin install time
  • StoragePersistence (user roles) refactored from a singleton to a class instantiated with storage
  • Default namespace is '' (empty string) → no prefix → fully backward compatible

Files refactored:

Key File(s)
mct-recent-objects src/ui/layout/RecentObjectsList.vue
mct-tree-expanded src/ui/layout/MctTree.vue
mct-pane-positions src/ui/layout/PaneContainer.vue
mct-saved-styles src/plugins/inspectorViews/styles/StylesManager.js
openmct-stored-view-prefs src/ui/layout/BrowseBar.vue, src/ui/router/Browse.js
openmct-shell-head src/ui/layout/AppLayout.vue
notebook-storage src/plugins/notebook/utils/notebook-storage.js
notebook-snapshot-storage src/plugins/notebook/snapshot-container.js
ACTIVE_USER_ROLE src/api/user/StoragePersistence.js
tcHistory* src/plugins/timeConductor/ConductorHistory.vue
openmct-listview-sort-order / storageKey src/plugins/folderView/components/ListView.vue, src/ui/components/List/ListView.vue
mct (spaceKey) src/plugins/localStorage/LocalStorageObjectProvider.js

All Submissions:

  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same update/change?
  • Is this a notable change that will require a special callout in the release notes? For example, will this break compatibility with existing APIs or projects that consume these plugins?

Author Checklist

  • Changes address original issue?
  • Tests included and/or updated with changes?
  • Has this been smoke tested?
  • Have you associated this PR with a type: label? Note: this is not necessarily the same as the original issue.
  • Have you associated a milestone with this PR? Note: leave blank if unsure.
  • Testing instructions included in associated issue OR is this a dependency/testcase change?

Reviewer Checklist

  • Changes appear to address issue?
  • Reviewer has tested changes by following the provided instructions?
  • Changes appear not to be breaking changes?
  • Appropriate automated tests included?
  • Code style and in-line documentation are appropriate?

Link to Devin session: https://app.devin.ai/sessions/9df1d5119fef4e4fbdd1b57e62809416
Requested by: @samanthataylor3


Devin Review

Status Commit
⚪ Not started

Run Devin Review

💡 Connect your GitHub account to enable automatic code reviews.

Open in Devin Review (Staging)

Resolves #5. Multiple Open MCT instances on the same host:port previously
collided on localStorage keys (e.g. 'mct-recent-objects', 'notebook-storage').

- Add StorageManager utility that prefixes keys with an optional namespace
- Register openmct.storage on the MCT instance; add setStorageNamespace() API
- Refactor all 12+ localStorage call sites to use openmct.storage
- Update LocalStorageObjectProvider to accept StorageManager
- Default namespace is empty string for backward compatibility
- Add unit tests for StorageManager prefix logic

Co-Authored-By: Samantha Taylor <samantha.taylor@cognition.ai>
@samanthataylor3 samanthataylor3 self-assigned this Jun 23, 2026
@devin-ai-integration

Copy link
Copy Markdown
Original prompt from Samantha

Fix GitHub Issue #5 in COG-GTM/openmct: Multiple Open MCT instances cause LocalStorage contention.

#``# Problem
Open MCT uses bare localStorage keys (e.g., 'mct-recent-objects', 'mct-tree-expanded', 'notebook-storage') for UI state persistence. When multiple Open MCT instances run on the same host:port, they collide on these keys.

#``# Plan

#``#``# Step 1: Create centralized StorageManager utility
Create src/utils/StorageManager.js:

class StorageManager {
  constructor(namespace = '') {
    this.namespace = namespace;
  }
  _prefixKey(key) {
    return this.namespace ? `${this.namespace}:${key}` : key;
  }
  getItem(key) {
    return window.localStorage.getItem(this._prefixKey(key));
  }
  setItem(key, value) {
    window.localStorage.setItem(this._prefixKey(key), value);
  }
  removeItem(key) {
    window.localStorage.removeItem(this._prefixKey(key));
  }
}
export default StorageManager;

#``#``# Step 2: Register StorageManager on the OpenMCT instance
In src/MCT.js (or wherever the OpenMCT class is defined), add:

import StorageManager from './utils/StorageManager.js';
// In constructor or install:
this.storage = new StorageManager(options.storageNamespace || '');

This lets users pass storageNamespace when creating their OpenMCT instance.

#``#``# Step 3: Refactor ALL localStorage call sites
Here is the complete list of files and keys to refactor:

Key File(s)
mct-recent-objects src/ui/layout/RecentObjectsList.vue
mct-tree-expanded src/ui/layout/MctTree.vue
mct-pane-positions src/ui/layout/PaneContainer.vue
mct-saved-styles src/plugins/inspectorViews/styles/StylesManager.js
openmct-stored-view-prefs src/ui/layout/BrowseBar.vue, src/ui/router/Browse.js
openmct-shell-head src/ui/layout/AppLayout.vue
notebook-storage src/plugins/notebook/utils/notebook-storage.js
notebook-snapshot-storage src/plugins/notebook/snapshot-container.js
`ACTIVE_USER_ROLE... (1151 chars truncated...)

@devin-ai-integration

Copy link
Copy Markdown

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

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.

Multiple Open MCT instances cause LocalStorage contention

1 participant