Is there a C# System.Reactive version of RxJava's doOnSubscribe? - system.reactive

In RxJava I tend to use Observable.doOnSubscribe to log when an observable is subscribed (to know when some work to create\fetch data is happening) to and found it useful to catch mistakes on when certain heavy work is invoked.
The Do() operator does seem to provide doOnNext(), doOnError(), doOnCompleted() RxJava functionality however uniess I'm missing it, it doesn't seem to provide functionality similar to doOnSubscribe().
I could add logging to the create\fetch data code however often this could be an Observable sourced via a 3rd party library and thus not as convenient vs having an operator such as RxJava's doOnSubscribe() it seems.
Am I missing the C# version of doOnSubscribe() or is there an alternative that would solve my needs?

Just use Observable.Defer():
var someObservable = ...;
var newObservable = Observable.Defer(() =>
{
Console.WriteLine("subscribed!");
return someObservable;
});
You can make your own extension if you wish:
public static IObservable<T> DoOnSubscribe(this IObservable<T> source, Action action)
{
return Observable.Defer(() =>
{
action();
return source;
});
}

Related

Does a FlowableOperator inherently supports backpressure?

I've implemented an FlowableOperator as described in the RxJava2 wiki (https://github.com/ReactiveX/RxJava/wiki/Writing-operators-for-2.0#operator-targeting-lift) except that I perform some testing in the onNext() operation something like that:
public final class MyOperator implements FlowableOperator<Integer, Integer> {
...
static final class Op implements FlowableSubscriber<Integer>, Subscription {
#Override
public void onNext(Integer v) {
if (v % 2 == 0) {
child.onNext(v * v);
}
}
...
}
}
This operator is part of a chain where I have a Flowable created with a backpressure drop. In essence, it looks almost like this:
Flowable.<Integer>create(emitter -> myAction(), DROP)
.filter(v -> v > 2)
.lift(new MyOperator())
.subscribe(n -> doSomething(n));
I've met the following issue:
backpressure occurs, so doSomething(n) cannot handle the upcoming upstream
items are dropped due to the Backpressure strategy chosen
but doSomething(n) never receives back new item after the drop has been performed and while doSomething(n) was ready to deal with new items
Reading back the excellent blog post http://akarnokd.blogspot.fr/2015/05/pitfalls-of-operator-implementations.html of David Karnok, it's seems that I need to add a request(1) in the onNext() method. But that was with RxJava1...
So, my question is: is this fix enough in RxJava2 to deal with my backpressure issue? Or do my operator have to implement all the stuff about Atomics, drain stuff described in https://github.com/ReactiveX/RxJava/wiki/Writing-operators-for-2.0#atomics-serialization-deferred-actions to properly handle my backpressure issue?
Note: I've added the request(1) and it seems to work. But I can't figure out whether it's enough or whether my operator needs the tricky stuff of queue-drain and atomics.
Thanks in advance!
Does a FlowableOperator inherently supports backpressure?
FlowableOperator is an interface that is called for a given downstream Subscriber and should return a new Subscriber that wraps the downstream and modulates the Reactive Streams events passing in one or both directions. Backpressure support is the responsibility of the Subscriber implementation, not this particular functional interface. It could have been Function<Subscriber, Subscriber> but a separate named interface was deemed more usable and less prone to overload conflicts.
need to add a request(1) in the onNext() [...]
But I can't figure out whether it's enough or whether my operator needs the tricky stuff of queue-drain and atomics.
Yes, you have to do that in RxJava 2 as well. Since RxJava 2's Subscriber is not a class, it doesn't have v1's convenience request method. You have to save the Subscription in onSubscribe and call upstream.request(1) on the appropriate path in onNext. For your case, it should be quite enough.
I've updated the wiki with a new section explaining this case explicitly:
https://github.com/ReactiveX/RxJava/wiki/Writing-operators-for-2.0#replenishing
final class FilterOddSubscriber implements FlowableSubscriber<Integer>, Subscription {
final Subscriber<? super Integer> downstream;
Subscription upstream;
// ...
#Override
public void onSubscribe(Subscription s) {
if (upstream != null) {
s.cancel();
} else {
upstream = s; // <-------------------------
downstream.onSubscribe(this);
}
}
#Override
public void onNext(Integer item) {
if (item % 2 != 0) {
downstream.onNext(item);
} else {
upstream.request(1); // <-------------------------
}
}
#Override
public void request(long n) {
upstream.request(n);
}
// the rest omitted for brevity
}
Yes you have to do the tricky stuff...
I would avoid writing operators, except if you are very sure what you are doing? Nearly everything can be achieved with the default operators...
Writing operators, source-like (fromEmitter) or intermediate-like
(flatMap) has always been a hard task to do in RxJava. There are many
rules to obey, many cases to consider but at the same time, many
(legal) shortcuts to take to build a well performing code. Now writing
an operator specifically for 2.x is 10 times harder than for 1.x. If
you want to exploit all the advanced, 4th generation features, that's
even 2-3 times harder on top (so 30 times harder in total).
There is the tricky stuff explained: https://github.com/ReactiveX/RxJava/wiki/Writing-operators-for-2.0

rxjava2 - how to pass in a consumer as parameter

i am using the following rxjava dependencies in android:
compile 'io.reactivex.rxjava2:rxjava:2.1.0'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
and i am trying to create a method that will take in a observer as a paramter. I am having some issues i think its because this is rxjava2 so things are updated and im a little confused.
Let me show you what i want to accomplish:
private Subscription subscription = Scriptions.empty(); //this isn't working. how to set a empty observer IN RXJAVA2?
protected abstract Observable buildUseCaseObservable(); //RETROFIT WILL BUILD THE OBSERVABLE FOR ME SOMEWHERE ELSE
public void execute(Consumer UseCaseSubscriber){
this.subscription = this.buildUseCaseObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(UseCaseSubscriber); //THIS LINE IS NOT WORKING , ERROR IS IN THE PHOTO
}
public void unsubscribe(){
if(!subscription.isUnsubscribed()){
subscription.unsubscribe();
}
}
Basically i am trying to create a method that will accept a observer/consumer as parameter and use that to update the UI after retrofit is done (being the observable).
UPDATE:
ok i changed it to disposables. now i'd like to store the disposable that i get back but its not working.
protected abstract Observable buildUseCaseObservable();
#SuppressWarnings("unchecked")
public void execute(Observer UseCaseSubscriber){
this.subscription = this.buildUseCaseObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(UseCaseSubscriber);
}
public void unsubscribe(){
if(!subscription.isUnsubscribed()){
subscription.unsubscribe();
}
}
i am getting the following warning:
The reason i want to store the whole thing in a subscription (or whatever else you recommend) is so i can unsubscribe to it whenever i want.
but from the docs:
Because Reactive-Streams base interface, org.reactivestreams.Publisher defines the subscribe() method as void, Flowable.subscribe(Subscriber) no longer returns any Subscription (or Disposable). The other base reactive types also follow this signature with their respective subscriber types.
so how to save disposable so we can unsubscribe then ?
Subscription has been 'renamed' to Disposable with 2.x version. You can read the rxJava wiki explanation on this change here.
so how to save disposable so we can unsubscribe then ? Flowable.subscribe(Subscriber) doesn't return disposable, but Observable.subscribe(Subscriber) does. If you don't need back-pressure, just cast your Flowable to Observable with .toObservable().

Linking to GWT instance method from JSNI does not automatically bind "this"

I am going to file this as a bug report, but I wanted to check if someone here can see something wrong with what I am doing.
When you expose an instance method from a GWT class through JSNI, this works as expected in JavaScript. Since we are cross compiling Java, I would instead expect this to be bound to the instance automatically. For example:
package com.test;
class Foo {
public void instanceFunction() {
this.otherFunction() // will cause an error when called from JSNI!
}
public void otherFunction() {
// does some stuff
}
public native JavaScriptObject getInstanceFunction() /*-{
return this.#com.test.Foo::instanceFunction();
}-*/;
}
Currently the workaround is to bind the function yourself (not very portable):
public native JavaScriptObject getInstanceFunction() /*-{
return this.#com.test.Foo::instanceFunction().bind(this);
}-*/;
This can also be seen as preference, some may prefer that the functions remain unbound. I would say the current functionality is unintuitave and unnecessary. I cannot imagine a use case for having an unbound this directly in Java code. Also, some browsers do not implement bind(1), so my workaround is not robust.
If you want a portable bind, it's as easy as:
var that = this;
return $entry(function() {
return that.#com.test.Foo::instanceFunction()();
});

Resolving a collection of services from a service type

I have a rather complex bit of resolving going on in Autofac. Basically I want all the objects in the container which implement a specifically named method with a specific argument type. I have implemented some somewhat insane code to get it for me
var services = (from registrations in _componentContext.ComponentRegistry.Registrations
from service in registrations.Services
select service).Distinct();
foreach (var service in services.OfType<Autofac.Core.TypedService>())
{
foreach (var method in service.ServiceType.GetMethods().Where(m => m.Name == "Handle"
&& m.GetParameters().Where(p => p.ParameterType.IsAssignableFrom(implementedInterface)).Count() > 0))
{
var handler = _componentContext.Resolve(service.ServiceType);
method.Invoke(handler, new Object[] { convertedMessage });
}
}
My problem arises in that the handler returned the the resolution step is always the same handler and I cannot see a way to resolve a collection of the the registrations which are tied to the service as one might normally do with container.Resolve>().
I feel like I'm pushing pretty hard against what AutoFac was designed to do and might do better with a MEF based solution. Is there an easy AutoFac based solution to this issue or should I hop over to a more composition based approach?
G'day,
In MEF you could use 'Method Exports' for this (http://mef.codeplex.com/wikipage?title=Declaring%20Exports) but that might be a bit drastic. There are a couple of ways to achieve what you want in Autofac.
You can make the above code work by searching for registrations rather than services:
var implementorMethods = _componentContext.ComponentRegistry.Registrations
.Select(r => new {
Registration = r,
HandlerMethod = r.Services.OfType<TypedService>()
.SelectMany(ts => ts.ServiceType.GetMethods()
.Where(m => m.Name == "Handle" && ...))
.FirstOrDefault()
})
.Where(im => im.HandlerMethod != null);
foreach (var im in implementorMethods)
{
var handler = _componentContext.ResolveComponent(im.Registration, new List<Parameter>());
im.HandlerMethod.Invoke(handler, new object[] { convertedMessage });
}
I.e. implementorMethods is a list of the components implementing a handler method, along with the method itself. ResolveComponent() doesn't rely on a service to identify the implementation, so there's no problem with the service not uniquely identifying a particular implementor.
This technique in general will probably perform poorly (if perf is a concern here) but also as you suspect will work against the design goals of Autofac (and MEF,) eliminating some of the benefits.
Ideally you need to define a contract for handlers that will let you look up all handlers for a message type in a single operation.
The typical recipe looks like:
interface IHandler<TMessage>
{
void Handle(TMessage message);
}
Handlers then implement the appropriate interface:
class FooHandler : IHandler<Foo> { ... }
...and get registered at build-time like so:
var builder = new ContainerBuilder();
builder.RegisterAssemblyTypes(typeof(FooHandler).Assembly)
.AsClosedTypesOf(typeof(IHandler<>));
To invoke the handlers, define a message dispatcher contract:
interface IMessageDispatcher
{
void Dispatch(object message);
}
...and then its implementation:
class AutofacMessageDispatcher : IMessageDispatcher
{
static readonly MethodInfo GenericDispatchMethod =
typeof(AutofacMessageDispatcher).GetMethod(
"GenericDispatch", BindingFlags.NonPublic | BindingFlags.Instance);
IComponentContext _cc;
public AutofacMessageDispatcher(IComponentContext cc)
{
_cc = cc;
}
public void Dispatch(object message)
{
var dispatchMethod = GenericDispatchMethod
.MakeGenericMethod(message.GetType());
dispatchMethod.Invoke(this, new[] { message });
}
void GenericDispatch<TMessage>(TMessage message)
{
var handlers = _cc.Resolve<IEnumerable<IHandler<TMessage>>>();
foreach (var handler in handlers)
handler.Handle(message);
}
}
...which is registered like so:
builder.RegisterType<AutofacMessageDispatcher>()
.As<IMessageDispatcher>();
The component that feeds in the messages will then resolve/use IMessageDispatcher to get the messages to the handlers.
var dispatcher = _cc.Resolve<IMessageDispatcher>();
dispatcher.Dispatch(message);
There are still ways to do this without the interface, but all rely on creating some kind of contract that uniquely defines handlers for a particular message (e.g. a delegate.)
In the long run the generic handler pattern will be the easiest to maintain.
Hope this helps, Nick.

How do I simplify these NUNit tests?

These three tests are identical, except that they use a different static function to create a StartInfo instance. I have this pattern coming up all trough my testcode, and would love
to be be able to simplify this using [TestCase], or any other way that reduces boilerplate code. To the best of my knowledge I'm not allowed to use a delegate as a [TestCase] argument, and I'm hoping people here have creative ideas on how to make the code below more terse.
[Test]
public void ResponseHeadersWorkinPlatform1()
{
DoResponseHeadersWorkTest(Platform1StartInfo.CreateOneRunning);
}
[Test]
public void ResponseHeadersWorkinPlatform2()
{
DoResponseHeadersWorkTest(Platform2StartInfo.CreateOneRunning);
}
[Test]
public void ResponseHeadersWorkinPlatform3()
{
DoResponseHeadersWorkTest(Platform3StartInfo.CreateOneRunning);
}
void DoResponseHeadersWorkTest(Func<ScriptResource,StartInfo> startInfoCreator)
{
ScriptResource sr = ScriptResource.Default;
var process = startInfoCreator(sr).Start();
//assert some things here
}
Firstly, I don't think the original is too bad. It's only messy if your assertions are different from test case to test case.
Anyway, you can use a test case, but it can't be done via a standard [TestCase] attribute due to using more complicated types. Instead, you need to use a public IEnumerable<> as the data provider and then tag your test method with a [TestCaseSource] attribute.
Try something like:
public IEnumerable<Func<ScriptResource, StartInfo>> TestCases
{
get
{
yield return Platform1StartInfo.CreateOneRunning;
yield return Platform2StartInfo.CreateOneRunning;
yield return Platform3StartInfo.CreateOneRunning;
}
}
[TestCaseSource("TestCases")]
public void MyDataDrivenTest(Func<ScriptResource, StartInfo> startInfoCreator)
{
ScriptResource sr = ScriptResource.Default;
var process = startInfoCreator(sr);
// do asserts
}
}
This is a more concise version of the standard pattern of yielding TestCaseData instances containing the parameters. If you yield instances of TestCaseData you can add more information and behaviours to each test (like expected exceptions, descriptions and so forth), but it is slightly more verbose.
Part of the reason I really like this stuff is that you can make one method for your 'act' and one method for your 'assert', then mix and match them independently. E.g. my friend was doing something yesterday where he used two Actions to say ("when method Blah is called, this method on the ViewModel should be triggered"). Very terse and effective!
It looks good. Are you looking to add a factory maybe ? Or you could add these methods to a Action List(in test setup) and call first action delegate, second action delegate and third action delegate.