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

Live Location Sharing - Attach location data to beacon info state event #5711

Merged
merged 8 commits into from
Apr 11, 2022

Conversation

onurays
Copy link
Contributor

@onurays onurays commented Apr 6, 2022

First m.beacon_info state event is sent and then m.beacon event with location data is sent by referencing the state event. Aggregating beacon info state event with the last location will be robust for UI rendering.

@onurays onurays requested review from a team and mnaturel and removed request for a team April 6, 2022 16:24
@github-actions
Copy link

github-actions bot commented Apr 6, 2022

Unit Test Results

114 files  +  4  114 suites  +4   1m 26s ⏱️ +13s
201 tests +  6  201 ✔️ +  6  0 💤 ±0  0 ±0 
674 runs  +24  674 ✔️ +24  0 💤 ±0  0 ±0 

Results for commit 1c5cf6b. ± Comparison against base commit 94099f4.

♻️ This comment has been updated with latest results.

Copy link
Contributor

@mnaturel mnaturel left a comment

Choose a reason for hiding this comment

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

I have some remarks to improve separation of code and about the process of the timestamps. How can I test if the events are well agregatted in database?

@@ -532,6 +546,49 @@ internal class EventRelationsAggregationProcessor @Inject constructor(
}
}

private fun handleLiveLocation(realm: Realm,
Copy link
Contributor

Choose a reason for hiding this comment

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

In my opininion, we clearly need to stop adding code to this class. It is too big. To separate easily the code, I propose using delegation pattern. The idea is:

  • create a dedicated package named aggregation.livelocation.
  • In this package, create an interface as follow:
interface LiveLocationAggregationProcessor {
    fun handleLiveLocation(realm: Realm,
                           event: Event,
                           content: MessageLiveLocationContent,
                           roomId: String,
                           isLocalEcho: Boolean)
}
  • In the same package create the class to implement the aggregation (moved from EventRelationsAggregationProcessor)
  • Finally make EventRelationsAggregationProcessor implements the LiveLocationAggregationProcessor interface using delegation:
EventRelationsAggregationProcessor(...) : LiveLocationAggregationProcessor by DefaultLiveLocationAggregationProcessor() {...}

This way we have a class dedicated to aggregating a single event type and it is easier to add unit tests on it.
What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, done. It is also easy to test now.

}

// A beacon info state event has to be sent before sending location
val beaconInfoEntity = CurrentStateEventEntity.getOrNull(realm, roomId, locationSenderId, EventType.STATE_ROOM_BEACON_INFO.first())
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be possible to check for both the stable and unstable prefixes for compaibility reason? And using first(), we are not sure to use the correct prefix since the list may change over time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, nice catch! Done.

private fun isBeaconInfoOutdated(beaconInfoContent: LiveLocationBeaconContent,
liveLocationContent: MessageLiveLocationContent): Boolean {
val beaconInfoStartTime = beaconInfoContent.getBestTimestampAsMilliseconds() ?: 0
val liveLocationEventTime = liveLocationContent.getBestTs() ?: 0
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible to do some renamings on MessageLiveLocationContent for the timestamps fields and the method getBestTs() to precise the unit and not use abreviation? For the method we would have getBestTimestampAsMilliseconds().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


private fun isBeaconInfoOutdated(beaconInfoContent: LiveLocationBeaconContent,
liveLocationContent: MessageLiveLocationContent): Boolean {
val beaconInfoStartTime = beaconInfoContent.getBestTimestampAsMilliseconds() ?: 0
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess we should first check if the beacon is still live before checking the timeout, what do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, so we need to set live=false to stop sharing live location.


// Update last location info of the beacon state event
beaconInfoContent.lastLocationContent = content
beaconInfoEntity.root?.content = ContentMapper.map(beaconInfoContent.toContent())
Copy link
Contributor

Choose a reason for hiding this comment

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

Out of curiosity, I don't understand how the write into the database of the new value is done. Can you explain?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I debugged on TimelineEventViewModel.init() like room.getStateEvent(EventType.STATE_ROOM_BEACON_INFO.first()).content. I don't want to block your work in timeline for now. But I am going to create integration tests next.

@onurays onurays requested a review from mnaturel April 8, 2022 10:27
Copy link
Contributor

@mnaturel mnaturel left a comment

Choose a reason for hiding this comment

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

Thanks for having extracted the aggregation into a dedicated component! I have added a small remaining comment.

}

// A beacon info state event has to be sent before sending location
val beaconInfoEntity = CurrentStateEventEntity.getOrNull(realm, roomId, locationSenderId, EventType.STATE_ROOM_BEACON_INFO.first())
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess we should check all values of the list of EventType.STATE_ROOM_BEACON_INFO in case the size of the list change in the future. Something like that:

var beaconInfoEntity: CurrentStateEventEntity? = null
val eventTypesIterator = EventType.STATE_ROOM_BEACON_INFO.iterator()
while (beaconInfoEntity == null && eventTypesIterator.hasNext()) {
    beaconInfoEntity = CurrentStateEventEntity.getOrNull(realm, roomId, locationSenderId, eventTypesIterator.next())
}

@onurays onurays requested a review from mnaturel April 11, 2022 10:15
@onurays onurays merged commit 5f635de into develop Apr 11, 2022
@onurays onurays deleted the feature/ons/live_location_aggregation branch April 11, 2022 12:02
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