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

Refactor native Map and Style to log error and not throw exception #1230

Merged
merged 11 commits into from
Mar 22, 2022

Conversation

kiryldz
Copy link
Contributor

@kiryldz kiryldz commented Mar 17, 2022

Summary of changes

Add MapboxMap.isValid() and Style.isValid() methods. Map and style become invalid when MapView.onDestroy is called: after that map and style objects are treated as not valid and accessing any method will cause printing error log and introduce a memory leak in user's code.

Another thing worse to mention - for async geojson parsing we do check for style being valid when parsing is over and we're about to send geojson to core.

Additionally going thru all our example activities to fix potential leaks.

User impact (optional)

That PR enhances public StyleInterface with a new method isValid(): Boolean. Technically that's a breaking change but this interface is not intended to be actually overwritten by user (and we do not provide any APIs to register such interfaces) so we treat this as an enhancement or bug fix.

That PR may break existing tests in case mocking StyleInterface in some very specific cases, this should be easily fixed with:

every { style.isValid() } returns true

Pull request checklist:

  • Briefly describe the changes in this PR.
  • Include before/after visuals or gifs if this PR includes visual changes.
  • Write tests for all new functionality. If tests were not written, please explain why.
  • Optimize code for java consumption (@JvmOverloads, @file:JvmName, etc).
  • Add example if relevant.
  • Document any changes to public APIs.
  • Run make update-api to update generated api files, if there's public API changes, otherwise the verify-api-* CI steps might fail.
  • Update CHANGELOG.md or use the label 'skip changelog', otherwise check changelog CI step will fail.
  • If this PR is a v10.[version] release branch fix / enhancement, merge it to main firstly and then port to v10.[version] release branch.

Fixes: < Link to related issues that will be fixed by this pull request, if they exist >

PRs must be submitted under the terms of our Contributor License Agreement CLA.

@kiryldz kiryldz self-assigned this Mar 17, 2022
@kiryldz kiryldz requested a review from a team as a code owner March 17, 2022 13:52
Copy link
Member

@tobrun tobrun left a comment

Choose a reason for hiding this comment

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

could we validate if having these strings inline doesn't result in a bunch of allocations/de-allocations with each function invocation? Else we need to make them constants instead

@yunikkk
Copy link
Contributor

yunikkk commented Mar 17, 2022

Should we also remove WeakRefs from NativeObserver and StyleObserver ?

@kiryldz
Copy link
Contributor Author

kiryldz commented Mar 17, 2022

@tobrun I do use String.format now as we did in v9 maps here assuming that code there is efficient, how does this sound to you? 😄

@tobrun
Copy link
Member

tobrun commented Mar 17, 2022

@tobrun I do use String.format now as we did in v9 maps here assuming that code there is efficient, how does this sound to you? smile

Yeah I was recently looking at that code and I was yikes this doesn't look good

@kiryldz
Copy link
Contributor Author

kiryldz commented Mar 17, 2022

@tobrun I do use String.format now as we did in v9 maps here assuming that code there is efficient, how does this sound to you? smile

Yeah I was recently looking at that code and I was yikes this doesn't look good

In any case it should not matter - hitting that if block and writing an error log should happen rarely and signalize that user is leaking style or map object. I guess we should not overthink here how efficiently string is built 😄

@kiryldz kiryldz force-pushed the kdz-refactor-native-map-style-ref branch from 0ef4224 to 1bacb77 Compare March 21, 2022 11:39
@kiryldz kiryldz force-pushed the kdz-refactor-native-map-style-ref branch from 1bacb77 to 01fd8f2 Compare March 21, 2022 11:43
@kiryldz kiryldz force-pushed the kdz-refactor-native-map-style-ref branch from 6978eee to e59e356 Compare March 21, 2022 15:32
CHANGELOG.md Outdated Show resolved Hide resolved
@@ -15,6 +15,12 @@ interface StyleInterface : StyleManagerInterface {
*/
val pixelRatio: Float

/**
Copy link
Contributor

Choose a reason for hiding this comment

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

We're 100% sure that interface is not implemented with any customer, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, it's our abstractions. While for plugin we potentially have a way to overwrite our default plugins - we do not have that for extensions and this interface is used with style extension only.
@pengdev @tobrun to confirm my understanding is correct here

Copy link
Member

Choose a reason for hiding this comment

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

StyleInterface is implemented in the SDK module itself, we allow user to overwrite the plugin implementations, but the SDK module itself shouldn't and couldn't be implemented by the end users.

The cases I can think of user use the StyleInterface is that they could mock it in their tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@pengdev sounds a bit strange to me still as we're operating with Style in our public API. Mostly it's one place:

/**
   * Callback to be invoked when a style has finished loading.
   */
  fun interface OnStyleLoaded {
    /**
     * Invoked when a style has finished loading.
     *
     * @param style the style that has finished loading
     */
    fun onStyleLoaded(style: Style)
  }

so for an end user guess it makes sense to mock Style then... In any case I'll drop instructions in PR description for that case.

Copy link
Member

Choose a reason for hiding this comment

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

👍 didn't remember we return Style async instead of StyleInterface

@kiryldz kiryldz requested a review from yunikkk March 22, 2022 10:29
Copy link
Contributor

@Chaoba Chaoba left a comment

Choose a reason for hiding this comment

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

Left a question, others LGTM. Thank you for taking this.

sdk/src/main/java/com/mapbox/maps/StyleObserver.kt Outdated Show resolved Hide resolved
@kiryldz kiryldz force-pushed the kdz-refactor-native-map-style-ref branch from 28cdc18 to f26c591 Compare March 22, 2022 14:42
@kiryldz kiryldz merged commit fde9cba into main Mar 22, 2022
@kiryldz kiryldz deleted the kdz-refactor-native-map-style-ref branch March 22, 2022 19:53
Comment on lines +99 to +102
if (!styleDelegate.isValid()) {
delegate = null
return@let
}
Copy link
Member

Choose a reason for hiding this comment

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

Would it make sense to add some error logs here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it's non-error situation - map destroyed while we were parsing so see no need in logs here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that code is not correct when using persistent layers, rollbacked in #1324

@@ -17,11 +17,11 @@ import com.mapbox.maps.extension.style.utils.silentUnwrap
fun StyleManagerInterface.getSource(sourceId: String): Source? {
Copy link
Member

Choose a reason for hiding this comment

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

Not in this release, but would consider to directly extend StyleInterface in the next major release.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍

Copy link
Member

@pengdev pengdev left a comment

Choose a reason for hiding this comment

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

LGTM with 1 comment, really like the documentation updates to the MapboxMap and Style, great work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants