-
Notifications
You must be signed in to change notification settings - Fork 731
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
Conversation
There was a problem hiding this 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, |
There was a problem hiding this comment.
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 theLiveLocationAggregationProcessor
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?
There was a problem hiding this comment.
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()) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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()
.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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()) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this 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()) |
There was a problem hiding this comment.
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())
}
First
m.beacon_info
state event is sent and thenm.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.