Flowable.compose() with org.reactivestreams.Processor<T, R> - rx-java2

Is there a way to .compose() a Flowable with an org.reactivestreams.Processor<T, R> to convert a Flowable<T> to a Flowable<R>?
Right now I'm .subscribe()'ing and then Flowable.fromPublisher()'ing the processor, but I'd like to be able to do something like
Flowable.just(t)
.compose(getProcessor())
.subscribe(r -> {});
instead of what I'm doing now:
Processor<T, R> processor = getProcessor();
Flowable.just(t).subscribe(processor);
Flowable.fromPublisher(processor).subscribe(r -> {});

Related

How to turn a proprietary stream into a Flux from spring webflux

I have a custom event bus where I can subscribe a lambda like
bus.subscribe(topic, event -> {/*gets executed for every new event*/}, exception -> {})
Now the lambda is obviously running in a different thread. Now my question is how can I connect this kind of interface to a Flux<Event>? do I have to write my own Publisher? But people say it's not a good idea to do so.
A mock implementation would be
import java.util.function.Consumer
class Mock extends Thread {
Consumer<String> lambda
public Mock(Consumer<String> lambda) {
this.lambda = lambda
}
#Override
void run() {
while(true) {
Thread.sleep(1000)
lambda.accept("lala")
}
}
}
Flux<String> flux = new Mock({ /*TODO write to flux*/ }).start()
You’re right, you should not implement your own publisher. In most cases, you should not have to deal with threads either and instead rely on static methods on Flux.
Something like:
Flux<Event> events = Flux.<Event>create(emitter -> {
bus.subscribe(topic, event -> emitter.next(event),
exc -> emitter.error(exc));
// you should also unsubscribe
emitter.onDispose(() -> {
bus.unsubscribe(topic, ...);
});
});

Possible to sort generic linked list in Java?

I'm trying to implement a k-means clustering algorithm (although that detail is not particularly important), and I wanted to make it work using generics in Java.
So in my main class I will call a cluster method. I was wondering if something like the following would be possible:
public static <T> void cluster(int k, LinkedList<T> list) {
// Sort the list
LinkedList<T> sortedList = Collections.sort(list);
...
}
Obviously the problem that I am running into is that T cannot be guaranteed to implement Comparable... But is there any way to achieve what I am trying to do?
This should work:
public static <T extends Comparable<T>> void cluster(int k, List<T> list) {
Collections.sort(list);
...
}
The <T extends Comparable<T>> makes sure that the List<T> holds Comparable<T> elements.
I used List<T> because the implementation (LinkedList, ArrayList etc.) doesn't matter - you access it via the List interface. But you can use LinkedList<T> instead if that's what you need.
And, Collections.sort() doesn't return anything, it sorts in-place.

RxJava- Placing several Observable values in a static body of text?

I have heard several reactive programming folks say "don't break the monad, just continue it". I see the merit in this. There are still certain instances I'm confused about, especially when the Observable is finally consumed or subscribed to. This is even more confusing when several observables have to be consumed at once, and it doesn't feel very practical to combine them into a single observable.
Let's say for instance I have a TrackedAircraft type. Some of its properties are final while other properties are Observable.
public interface TrackedAircraft {
public int getFlightNumber();
public int getCapacity();
public Observable<String> getOrigin();
public Observable<String> getDestination();
public Observable<Integer> getMileage();
public Observable<Point> getLocation();
}
I could wire this to a GUI pretty easily, and just subscribe controls to be updated with each emission of each property. But what about an email or a body of static text? This is not as straightforward because the only way I can think of not breaking the monad is to combine all the observables which sounds like a pain especially if I have an Observable emitting TrackedFlights.
Is it okay to block in this situation? Or is there a more monadic way to accomplish this I haven't thought of?
public static String generateEmailReportForFlight(TrackedAircraft flight) {
return new StringBuilder().append("FLIGHT NUMBER: ").append(flight.getFlightNumber()).append("\r\n")
.append("CAPACITY: ").append(flight.getCapacity()).append("\r\n")
.append("ORIGIN: ").append(flight.getOrigin() /*What do I do here without blocking?*/)
.append("DESTINATION: ").append(flight.getDestination() /*What do I do here without blocking?*/)
.append("MILEAGE: ").append(flight.getMileage() /*What do I do here without blocking?*/)
.append("LOCATION: ").append(flight.getLocation() /*What do I do here without blocking?*/)
.toString();
}
///
Observable<TrackedAircraft> trackedFlights = ...;
trackedFlights.map(f -> generateEmailReportForFlight(f));
You can use flatMap + combineLatest:
Observable<TrackedAircraft> trackedFlights = ...
trackedFlights
.flatMap(flight -> emailReport(flight))
.subscribe(msg -> sendEmail(msg));
Observable<String> emailReport(TrackedAircraft flight) {
return Observable.combineLatest(
flight.getOrigin(),
flight.getDestination(),
flight.getMileage(),
flight.getLocation()
(origin, destination, mileage, location) -> {
return new StringBuilder()
.append("FLIGHT NUMBER: ").append(flight.getFlightNumber())
.append("\r\n")
.append("CAPACITY: ").append(flight.getCapacity())
.append("\r\n")
.append("ORIGIN: ").append(origin)
.append("\r\n")
.append("DESTINATION: ").append(destination)
.append("\r\n")
.append("MILEAGE: ").append(mileage)
.append("\r\n")
.append("LOCATION: ").append(location)
.toString();
}
)
}

Delay items emission until item is emitted from another observable

Playing with RxJava now and stumbled upon the following problem:
I have 2 different streams:
Stream with items
Stream (with just 1 item) which emits transformation information for the first stream.
So essentially I have stream of items and I want all those items to be combined with that single item from 2nd stream:
----a1----a2----a3----a4----a5----|--------------->
-------------b1--|----------------------------------->
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
------------a1b1-a2b1-a3b1-a4b1-a5b1-------->
It looks really similar to combileLatest operator, but combineLatest will ignore all items from the first stream except the closest to the item from the second stream. It means that I will not receive a1b1 - the first resulting item emitted is gonna be a2b1.
I also looked at delay operator, but it doesn't allow me to specify close stream like it is done with buffer operatior
Is there any fancy operator which solves the problem above?
There are several ways of making this happen:
1) flatMap over b if you don't need to start a upfront
b.flatMap(bv -> a.map(av -> together(av, bv)));
2) You can, of course, cache but it will retain your as for the entire duration of the stream.
3) Use groupBy a bit unconventionally because its GroupedObservable caches values until the single subscriber arrives, replays the cached value and continues as a regular direct observable (letting all previous cached values go).
Observable<Long> source = Observable.timer(1000, 1000, TimeUnit.MILLISECONDS)
.doOnNext(v -> System.out.println("Tick"))
.take(10);
Observable<String> other = Observable.just("-b").delay(5000, TimeUnit.MILLISECONDS)
.doOnNext(v -> System.out.println("Tack"))
;
source.groupBy(v -> 1)
.flatMap(g ->
other.flatMap(b -> g.map(a -> a + b))
).toBlocking().forEach(System.out::println);
It works as follows:
Get a hold onto a GroupedObservable by grouping everything from source into group 1.
when the group g arrives, we 'start observing' the other observable.
Once other fires its element, we take it and map it over the group and 'start observing' it as well, bringing us the final sequence of a + bs.
I've added doOnNexts so you can see the source is really active before the other fires its "Tack".
AFAIK, there is no a built-in operator to achieve the behavior you've described. You can always implement a custom operator or build it on top of existing operators. I think the second option is easier to implement and here is the code:
public static <L, R, T> Observable<T> zipper(final Observable<? extends L> left, final Observable<? extends R> right, final Func2<? super L, ? super R, ? extends T> function) {
return Observable.defer(new Func0<Observable<T>>() {
#Override
public Observable<T> call() {
final SerialSubscription subscription = new SerialSubscription();
final ConnectableObservable<? extends R> cached = right.replay();
return left.flatMap(new Func1<L, Observable<T>>() {
#Override
public Observable<T> call(final L valueLeft) {
return cached.map(new Func1<R, T>() {
#Override
public T call(final R valueRight) {
return function.call(valueLeft, valueRight);
}
});
}
}).doOnSubscribe(new Action0() {
#Override
public void call() {
subscription.set(cached.connect());
}
}).doOnUnsubscribe(new Action0() {
#Override
public void call() {
subscription.unsubscribe();
}
});
}
});
}
If you have any questions regarding the code, I can explain it in details.
UPDATE
Regarding the questing how my solution is different from the following one:
left.flatMap(valueLeft -> right.map(valueRight -> together(valueLeft, valueRight)));
Parallel execution - in my implementation both left and right observables are executing in parallel. right observable doesn't have to wait for a left one to emit its first item.
Caching - my solution subscribes only once to the right observables and caches its result. Thats why b1 will always be the same for all aXXX items. The solution provided by akarnokd subscribes to the rightobservable every time the left one emits an item. That means:
There is no guarantee that b1 won't change its value. For example for the following observable you will get a different b for each a.
final Observable<Double> right = Observable.defer(new Func0<Observable<Double>>() {
#Override
public Observable<Double> call() {
return Observable.just(Math.random());
}
});
If the right observable is a time consuming operation (e.g. network call), you will have to wait for its completion every time the left observable emits a new item.

Gtk+ and Vala: Inheriting gtk.TreeModel

I have a hash with values that build into following structure:
string type1_name -> Hash(
string name_member -> DataStruct,
string name_member -> DataStruct,
string name_member -> DataStruct,
string name_member -> DataStruct
),
string type2_name -> Hash(
string name_member -> DataStruct,
string name_member -> DataStruct,
string name_member -> DataStruct,
string name_member -> DataStruct
),
/// etc
the problem is I have 3 views: 2 TreeViews (extended actual tree showing all columns in hierarchial way and brief as ListStore showing only type icon and name of DataStruct, those views are owned by different parents and maybe shown at the same time) and 1 ListView with icon representation of same data. ATM I have a class managing data (validations, serialization, deserialization, ...) and 3 models for each of those views, so every time I update/delete/create item I must update all 3 models and that doesn't look good :(
What I thought about is creating a class implementing Gtk.TreeModel and providing common data source that can be used as model for all 3 views, but I can't find any documentation on how to implement gtk.TreeModel. I've tried to look through GtkListStore (native C implementaion) and I see it reimplements really lots of methods. Isn't there any easier way?
No, there isn't an easier way, but it's really not too difficult. Looking at the C code can be intimidating, but there are really only about a dozen methods which you need to implement. They are marked as abstract in gtk+-3.0.vapi (and in valadoc.org's Gtk.TreeModel docs)., and the implementations are usually pretty trivial. If you want an example SQLHeavyGtk.Model is the only one I can think of.
The methods which are marked as virtual don't generally require an implementation, though you can provide one if you want (often used for optimizations, and I'm guessing Gtk.ListStore provides a lot of them).
Simple inherit from Gtk.TreeStore / Gtk.ListStore and set the column types explicit.
The tree view column is set to the cell renderer and the data callback function you like to show.
Vala sample to map MyCommon.data1 to the treeview1.column = 0
public class MyCommon : GLib.Object {
string data1 {get; set; }
string data2 {get; set; }
}
public class Store : Gtk.TreeStore {
public Store() {
set_column_types( new GLib.Type[] { typeof(MyCommon) } );
}
public set_treeview1(Gtk.TreeView treeview) {
treeview.insert_column_with_data_func(0, "data1", new Gtk.CellRendererText(), tree_cell_data1);
treeview.insert_column_with_data_func(1, "data2", new Gtk.CellRendererText(), tree_cell_data2);
treeview.model = this;
}
protected MyCommon? my_common(Gtk.TreeModel model, Gtk.TreeIter iter) {
GLib.Value data;
model.get_value(iter, 0, out data);
return (MyCommon)data;
}
public void tree_cell_data1(Gtk.TreeViewColumn column, Gtk.CellRenderer cell,
Gtk.TreeModel model, Gtk.TreeIter iter) {
MyCommon? property = my_common(this,iter);
if(property != null) (cell as Gtk.CellRendererText).text = property.data1;
}
public void tree_cell_data2(Gtk.TreeViewColumn column, Gtk.CellRenderer cell,
Gtk.TreeModel model, Gtk.TreeIter iter) {
MyCommon? property = my_common(this,iter);
if(property != null) (cell as Gtk.CellRendererText).text = property.data2;
}
.....