ursus
12/02/2022, 2:48 AMbeginsAt: Timestamp
on it
I need to render a list of those meetings, and color red those which are say, 15 minutes before beginning.
Now, I’d best like to use a combineLatest, however that requires a “time” stream to combine with.
I could have a stream which emits every say seconds, but that feels like a waste
So my attempt, I observe the stream, and calculate the delta time from now and “15min before beginning”, and timer
to emit then.
Now, the question is, should I use this only as a “tickle” into the combineLatest, and let it’s combiner to reevaluate the “15min before beginning” condition in it
combine(meetings, timer, ::combiner)
Or,
should I treat timer
as the trusted, and then just set the meeting’s color directly, i.e. don’t reevaluate the condition?
--
I like the former, however it requires for the timer
not emit before the given deadline.
Is it to be trusted to not do so?uli
12/02/2022, 4:24 PMursus
12/02/2022, 4:33 PMuli
12/02/2022, 4:34 PMursus
12/02/2022, 4:35 PMcombine(meetings, reevaluateTrigger).map { (meetings, _) -> evaluateStuff(meetings, clock.now) }
uli
12/02/2022, 4:35 PMursus
12/02/2022, 4:36 PMuli
12/02/2022, 4:38 PMuli
12/02/2022, 4:38 PMmeeting color doesnt change and nothing else is enqueued
Why would you not enqueue eny thing?
the meeting is 1 sec in the future. so you should schedule a new trigger in 1sursus
12/02/2022, 4:40 PMmeetings
.map { it.sortBy(beginsAt).firstOrNull() }
.flatMap {
if (it == null) emptyFlow() else timerFlow(it.beginsAt - clock.now - 15min) }
}
.collect {
reevaluateTrigger.emit(somethingUniqueue())
}
uli
12/02/2022, 4:43 PMit.beginsAt - clock.now
be 1s?
And do you mean:
(it.beginsAt - 15min) - clock.now
ursus
12/02/2022, 4:43 PMuli
12/02/2022, 4:44 PMuli
12/02/2022, 4:44 PMursus
12/02/2022, 4:44 PMuli
12/02/2022, 4:44 PMuli
12/02/2022, 4:45 PMursus
12/02/2022, 4:46 PMcombine
get reevaluated, nothing changes since time is still before 15min till the meetingursus
12/02/2022, 4:47 PMmeetings
.map { it.sortBy(beginsAt).firstOrNull() }
.flatMap {
if (it == null) emptyFlow() else timerFlow(it.beginsAt - clock.now - 15min) }
}
.collect {
reevaluateTrigger.emit(somethingUniqueue())
}
doesn’t get triggered againursus
12/02/2022, 4:48 PMuli
12/02/2022, 4:48 PMursus
12/02/2022, 4:49 PMursus
12/02/2022, 4:49 PMuli
12/02/2022, 4:50 PMursus
12/02/2022, 4:51 PMmeetings
wont emit againursus
12/02/2022, 4:51 PMursus
12/02/2022, 4:52 PMcombine(meetings, trigger)
.map { (meetings, _) -> mapToColoredMeetings(meetings, clock.now) }
.collect { coloredMeetings -> renderUi(coloredMeetings) }
data class Meetings(id, beginsAt)
data class ColoredMeetings(id, beginsAt, color)
uli
12/02/2022, 4:55 PMmeetingsFlow
.flatMap { meetings ->
val nextMeeting = meetings.minOfOrNull(it.beginsAt)
val nextTriggerAt = (nextMeeting - 15min) - clock.now
val timerFlow = if (nextTime == null) emptyFlow() else timerFlow(nextTriggerAt) }
timerFlow.map { meetings }
}
.collect { meetings ->
// This will fire whenever the meetings change or the timer triggers
}
Only when there are no more meetings will this stop to emit.
If you then add a new meeting, the meetingsFlow will restart the machinery.uli
12/02/2022, 5:03 PM.map { meetings ->
mapToColoredMeetings(meetings, clock.now) }
.collect { coloredMeetings ->
renderUi(coloredMeetings) }
}
uli
12/02/2022, 5:06 PMuli
12/02/2022, 5:07 PMuli
12/02/2022, 5:07 PMursus
12/02/2022, 5:11 PMmeetings
.transformLatest { meetings ->
emit(tuple(meetings, clock.now))
val nextMeetingBegingsAt = it.sortBy(beginsAt).firstOrNull()
if (nextMeetingBeginsAt != null) {
delay(nextMeetingBegingsAt - clock.now - 15min + FUDGE_FACTOR)
emit(tuple(meetings, clock.now))
}
}
is more elegant