Skip to content

Improve EmoTracker.Core performance, thread safety, and API flexibility#65

Open
emosaru wants to merge 1 commit intomainfrom
worktree-core-audit-improvements
Open

Improve EmoTracker.Core performance, thread safety, and API flexibility#65
emosaru wants to merge 1 commit intomainfrom
worktree-core-audit-improvements

Conversation

@emosaru
Copy link
Copy Markdown
Contributor

@emosaru emosaru commented Apr 22, 2026

Summary

  • P1 — Cache type-tag lookups in JsonTypeTagsAttribute to avoid lock contention and full type scan on every deserialization call; rename CreateIntanceForTypeTagCreateInstanceForTypeTag (typo fix)
  • P5 — Fix ObservableCollectionExtensions.Sort O(n^2) by avoiding repeated IndexOf
  • P6 — Use object lock instead of string literal "Registry" in TypeRegistry/TypedObjectRegistry to eliminate cross-type deadlock risk from string interning
  • P7 — Fix TypedObjectRegistry null deref when ReflectionTypeLoadException.LoaderExceptions is null
  • P8 — Add try/catch on TypeRegistry.GetTypes() to prevent crash on assemblies with missing dependencies
  • A1 — Add Invoke<T>(Func<T>), Invoke(Func<Task>), BeginInvoke(Func<Task>) to dispatch service backend, eliminating TaskCompletionSource workarounds
  • A2 — Add exception-aware Debug/Info/Warn/Error(Exception, ...) overloads to log service backend for structured logging support
  • A3 — Add CancellationToken parameter and Cancel() method to all collection synchronizers and their derived classes
  • T1 — Use Interlocked.Exchange for mActiveBackend in Log/Dispatch service backends to prevent TOCTOU race during backend swaps

Test plan

  • Build solution: dotnet build EmoTracker/EmoTracker.csproj — passes clean
  • Verify JsonTypeTagsAttribute.CreateInstanceForTypeTag works with cached dictionary for multiple type arguments
  • Verify ObservableCollectionSynchronizerMT and BufferedObservableCollectionSynchronizerMT Cancel() overrides work
  • Verify new dispatch overloads (Invoke<T>, Invoke(Func<Task>), BeginInvoke(Func<Task>)) work correctly in the UI
  • Verify exception-aware logging (Log.Error(ex, ...)) forwards exception to Serilog correctly
  • Verify TypeRegistry and TypedObjectRegistry don't crash when assemblies have missing dependencies

🤖 Generated with Claude Code

Performance:
- Cache type-tag lookups in JsonTypeTagsAttribute to avoid lock contention and
  full type scan on every deserialization call; rename CreateIntanceForTypeTag
  to CreateInstanceForTypeTag (typo fix)
- Fix ObservableCollectionExtensions.Sort O(n^2) by avoiding repeated IndexOf
- Use object lock instead of string literal in TypeRegistry/TypedObjectRegistry
  to eliminate cross-type deadlock risk from string interning
- Fix TypeRegistry.GetTypes() crash when assembly has missing dependencies
  (add try/catch, matching TypedObjectRegistry's defensive pattern)
- Fix TypedObjectRegistry null deref when ReflectionTypeLoadException has
  null LoaderExceptions property

API additions:
- Add Invoke<T>(Func<T>), Invoke(Func<Task>), BeginInvoke(Func<Task>) to
  DispatchService backend, eliminating TaskCompletionSource workarounds
- Add exception-aware Debug/Info/Warn/Error overloads to LogService backend
  for structured logging support
- Add CancellationToken parameter and Cancel() method to all collection
  synchronizers (ObservableCollectionSynchronizer,
  ObservableCollectionAggregatorSynchronizer,
  ObservableCollectionUniqueSetAggregrator and all derived classes)

Thread safety:
- Use Interlocked.Exchange for mActiveBackend in Log and Dispatch service
  backends to prevent TOCTOU race when swapping backends

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@emosaru emosaru requested a review from a team April 22, 2026 08:39
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