Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow external ownership for Modules #106

Merged
merged 8 commits into from
Jun 26, 2024

Conversation

Supereg
Copy link
Member

@Supereg Supereg commented Jun 23, 2024

Allow external ownership for Modules

♻️ Current situation & Problem

When loading modules dynamically using loadModule(_:), Spezi always takes ownership of the Module. Spezi keeps a strong reference until unloadModule(_:) is called. This isn't strictly necessary (with some conditions applying). In some cases it is helpful for framework engineers to not pass ownership to Spezi. Namely, one can make use of being notified when objects are de-initialized (e.g., a framework creating a Module and passing ownership to the framework user and relying on the deinit to be notified when the user deallocated the object).

This PR introduces the concept of ModuleOwnership that can be passed to the updated loadModule(_:ownership:) method. external ownership is available to framework developers via the APISupport SPI.
When specifying external ownership does not keep any strong references to the loaded Module. This required making some changes how resources are automatically cleared (e.g., @Dependency, @Provide, @Modifier or @Model modifiers automatically clean up their resources once their are deallocated). Some features like EnvironmentAccessible are not available when using external ownership as they would inherently imply strong ownership.
Other modules that depend on such modules either maintain a weak reference if they declare it as an optional dependency (in this case the dependency is automatically removed once the Module de-initializes) or a strong reference if declared as a required dependency. In such a case, ownership is shared with that module for the lifetime of the module that declares a required dependency to an externally managed module.

⚙️ Release Notes

  • Add support for dynamically loading Modules with external ownership.

📚 Documentation

Documentation was updated for changed interfaces.

✅ Testing

Additional unit testing was added to verify functionality of dynamically loaded modules with external ownership.

📝 Code of Conduct & Contributing Guidelines

By submitting creating this pull request, you agree to follow our Code of Conduct and Contributing Guidelines:

@Supereg Supereg marked this pull request as ready for review June 23, 2024 20:29
Copy link

codecov bot commented Jun 23, 2024

Codecov Report

Attention: Patch coverage is 86.57718% with 40 lines in your changes missing coverage. Please review.

Project coverage is 87.64%. Comparing base (734f90c) to head (1855025).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #106      +/-   ##
==========================================
- Coverage   87.93%   87.64%   -0.28%     
==========================================
  Files          42       46       +4     
  Lines        1217     1375     +158     
==========================================
+ Hits         1070     1205     +135     
- Misses        147      170      +23     
Files Coverage Δ
...ilities/Communication/CollectPropertyWrapper.swift 100.00% <100.00%> (ø)
...bilities/Communication/CollectedModuleValues.swift 100.00% <100.00%> (+18.52%) ⬆️
...ilities/Communication/ProvidePropertyWrapper.swift 100.00% <100.00%> (ø)
...ifications/RegisterRemoteNotificationsAction.swift 85.11% <ø> (ø)
...ications/UnregisterRemoteNotificationsAction.swift 100.00% <ø> (ø)
...apabilities/Observable/EnvironmentAccessible.swift 100.00% <100.00%> (ø)
...Capabilities/Observable/ModelPropertyWrapper.swift 66.67% <100.00%> (+8.61%) ⬆️
...ies/ViewModifier/ModelModifierInitialization.swift 100.00% <100.00%> (ø)
...ilities/ViewModifier/ModifierPropertyWrapper.swift 77.78% <100.00%> (+6.35%) ⬆️
...apabilities/ViewModifier/WrappedViewModifier.swift 100.00% <100.00%> (ø)
... and 15 more

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 734f90c...1855025. Read the comment docs.

Copy link
Member

@PSchmiedmayer PSchmiedmayer left a comment

Choose a reason for hiding this comment

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

Nice work @Supereg; great addition to the overall system design for Spezi!

Only major point I would see is the SwiftLint dependency for the main package. I would propose to rather move that to the UI Testing Application as the main point to develop the package, run all tests, and display linting warnings inside. Let me know what you think and how you want to proceed here.

We might need to wait for SPM to become smarter and not checking out and/or building buildtime or testing dependencies when using a SP as a dependency ...

Package.swift Outdated Show resolved Hide resolved
Tests/SpeziTests/DependenciesTests/DependencyTests.swift Outdated Show resolved Hide resolved
Copy link
Member

@PSchmiedmayer PSchmiedmayer left a comment

Choose a reason for hiding this comment

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

Thank you for the improvements; looks great!

@Supereg Supereg merged commit 5ada3f3 into main Jun 26, 2024
13 checks passed
@Supereg Supereg deleted the feature/externally-managed-modules branch June 26, 2024 16:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

2 participants