-
Notifications
You must be signed in to change notification settings - Fork 7.6k
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
2.x: Improve the Observable/Flowable cache() operators #6275
Conversation
Codecov Report
@@ Coverage Diff @@
## 2.x #6275 +/- ##
============================================
- Coverage 98.22% 98.22% -0.01%
- Complexity 6213 6257 +44
============================================
Files 667 667
Lines 44905 44887 -18
Branches 6228 6213 -15
============================================
- Hits 44110 44089 -21
- Misses 251 255 +4
+ Partials 544 543 -1
Continue to review full report at Codecov.
|
@@ -35,7 +35,7 @@ | |||
public class ObservableCacheTest { | |||
@Test | |||
public void testColdReplayNoBackpressure() { | |||
ObservableCache<Integer> source = (ObservableCache<Integer>)ObservableCache.from(Observable.range(0, 1000)); | |||
ObservableCache<Integer> source = (ObservableCache<Integer>)new ObservableCache<Integer>(Observable.range(0, 1000), 16); |
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 the cast really needed now?
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.
So the test can access the the package-private methods verifying the internal state.
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.
Either I'm missing something or
ObservableCache<Integer> source = (ObservableCache<Integer>)new ObservableCache<Integer>(Observable.range(0, 1000), 16);
can just be
ObservableCache<Integer> source = new ObservableCache<Integer>(Observable.range(0, 1000), 16);
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.
You are right. Updated.
@@ -351,4 +351,23 @@ public void run() { | |||
.assertSubscribed().assertValueCount(500).assertComplete().assertNoErrors(); | |||
} | |||
} | |||
|
|||
@Test | |||
public void cancelledUpFront() { |
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.
Flowable has this test?
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.
Yes it has.
void remove(CacheSubscription<T> consumer) { | ||
for (;;) { | ||
CacheSubscription<T>[] current = subscribers.get(); | ||
int n = current.length; |
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.
nit: final
long index = consumer.index; | ||
int offset = consumer.offset; | ||
Node<T> node = consumer.node; | ||
AtomicLong requested = consumer.requested; |
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.
Maybe remove this reference? It looks like the value is captured here and it's a bit misleading
I doubt you win much by capturing it here
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.
It is accessed every turn as it doubles as the cancelled indicator.
@SuppressWarnings("unchecked") | ||
void remove(CacheSubscription<T> consumer) { | ||
for (;;) { | ||
CacheSubscription<T>[] current = subscribers.get(); |
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.
nit: final
int offset = consumer.offset; | ||
Node<T> node = consumer.node; | ||
AtomicLong requested = consumer.requested; | ||
Subscriber<? super T> downstream = consumer.downstream; |
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 be great to mark what's possible as final here to improve readability
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.
It's not our style.
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.
Yea, I think I was overexcited to push code readability a bit further after recent rewrites you've done with multi-character variable names and comments :D
@@ -951,11 +951,11 @@ public void accept(String v) { | |||
@Test | |||
public void testUnsubscribeSource() throws Exception { | |||
Action unsubscribe = mock(Action.class); | |||
Flowable<Integer> f = Flowable.just(1).doOnCancel(unsubscribe).cache(); | |||
Flowable<Integer> f = Flowable.just(1).doOnCancel(unsubscribe).replay().autoConnect(); |
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.
ouch
This PR rewrites the
Observable.cache
andFlowable.cache
operators to allocate less and be more up-to-date algorithmically.I've also added comments to help understand its inner workings in case someone is interested.
Resolves: #6270