I am still struggling with some of the basics of RxJava and would greatly appreciate some help.
I have an infinite, hot observable which emits regularly tagged events (captures in a simple class having a name (tag) and some properties). The tags are finite (in this case about 10 distinct tags) but the event specifics are every time different (a time stamp, say).
What I am trying to do now is to create a HashMap with the tags as key and the events as the entry, such that the HashMap itself becomes an infinite observable which emits the HashMap with every change.
So far, I used a Subject to subscribe to the original observable and to emit the HashMap, but I also saw the ".toMap" method. However, I cannot figure out how use that method with an infinite observable source and emit with every change. From the documentation it is not even clear to me whether this would be possible at all.
If it's not possible, is there another way, aside from using Subjects, to achieve the same? I want to keep this lean, and Subject seems rather heavy.
Here is my code convert it to a Map or Observable<Map>. But I don't know why you need to do this.
fun <T, K> Observable<T>.toInfiniteMap(keySelector: (T) -> K): Map<K, Observable<T>> {
val map = ConcurrentHashMap<K, Observable<T>>()
this.subscribeOn(Schedulers.newThread())
.doOnNext { println(it) }
.groupBy(keySelector)
.doOnNext { map.put(it.getKey(), it) }
.subscribe()
return map
}
fun <T, K> Observable<T>.toInfiniteMapObservable(keySelector: (T) -> K):
Observable<Map<K, Observable<T>>> {
val map = ConcurrentHashMap<K, Observable<T>>()
return this.subscribeOn(Schedulers.newThread())
.doOnNext { println(it) }
.groupBy(keySelector)
.doOnNext { map.put(it.getKey(), it) }
.map { map }
}
Related
The Code A is based the article.
I was told that if the function writes to a local variable, this code will not be thread-safe or correct, and I will get the wrong result.
1: I test it with the Code A, but I always get the correct result, why?
2: Is the Code B correct?
Code A
#Composable
fun ListWithBug(myList: List<String>) {
var items = 0
Row(horizontalArrangement = Arrangement.SpaceBetween) {
Column {
for (item in myList) {
Text("Item: $item")
items++ // Avoid! Side-effect of the column recomposing.
}
}
Text("Count: $items")
}
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApp {
ListWithBug(mutableListOf("a","b","c","d","e","f","g","h","k","j"))
}
}
}
}
Code B
#Composable
fun ListWithBug(myList: List<String>) {
var items by remember { mutableStateOf(0) }
Row(horizontalArrangement = Arrangement.SpaceBetween) {
Column {
for (item in myList) {
Text("Item: $item")
items++ // Avoid! Side-effect of the column recomposing.
}
}
Text("Count: $items")
}
}
It will not work as expected under practical scenarios. It might be working for you because you are testing it in isolation. Whenever a Composable recomposes, it will re-initialise all the variables that are declared in it. Hence, if something s=triggers a recomposition of the Composable, it will re-initialise the items var to 0. I said it would not work in practical application because over that place, there's a pool of composables the user is interacting with. A press of a button could cause multiple recompositions so it is not at all safe to maintain this state in the local composable.
The second approach MIGHT be fine, but is not at all recommended since it can cause state inconsistency among other composables, because ideally, you should store all of your UI state in a viewmodel. It acts as a single source of truth and all the composables can read the state from a single place that way.
You can learn about state hoisting in order to use viewmodels consistently with Compose. Just check out this codelab.
Maybe specifically this page, but surely give a go to the codelab on the whole.
Recently I started to learn Rust and one of my main struggles is converting years of Object Oriented thinking into procedural code.
I'm trying to parse a XML that have tags that are processed by an specific handler that can deal with the data it gets from the children.
Further more I have some field members that are common between them and I would prefer not to have to write the same fields to all the handlers.
I tried my hand on it and my code came out like this:
use roxmltree::Node; // roxmltree = "0.14.0"
fn get_data_from(node: &Node) -> String {
let tag_name = get_node_name(node);
let tag_handler: dyn XMLTagHandler = match tag_name {
"name" => NameHandler::new(),
"phone" => PhoneHandler::new(),
_ => DefaultHandler::new()
}
if tag_handler.is_recursive() {
for child in node.children() {
let child_value = get_data_from(&child);
// do something with child value
}
}
let value: String = tag_handler.value()
value
}
// consider that handlers are on my project and can be adapted to my needs, and that XMLTagHandler is the trait that they share in common.
My main issues with this are:
This feels like a Object oriented approach to it;
is_recursive needs to be reimplemented to each struct because they traits cannot have field members, and I will have to add more fields later, which means more boilerplate for each new field;
I could use one type for a Handler and pass to it a function pointer, but this approach seems dirty. e.g.:=> Handler::new(my_other_params, phone_handler_func)
This feels like a Object oriented approach to it
Actually, I don't think so. This code is in clear violation of the Tell-Don't-Ask principle, which falls out from the central idea of object-oriented programming: the encapsulation of data and related behavior into objects. The objects (NameHandler, PhoneHandler, etc.) don't have enough knowledge about what they are to do things on their own, so get_data_from has to query them for information and decide what to do, rather than simply sending a message and letting the object figure out how to deal with it.
So let's start by moving the knowledge about what to do with each kind of tag into the handler itself:
trait XmlTagHandler {
fn foreach_child<F: FnMut(&Node)>(&self, node: &Node, callback: F);
}
impl XmlTagHandler for NameHandler {
fn foreach_child<F: FnMut(&Node)>(&self, _node: &Node, _callback: F) {
// "name" is not a recursive tag, so do nothing
}
}
impl XmlTagHandler for DefaultHandler {
fn foreach_child<F: FnMut(&Node)>(&self, node: &Node, callback: F) {
// all other tags may be recursive
for child in node.children() {
callback(child);
}
}
}
This way you call foreach_child on every kind of Handler, and let the handler itself decide whether the right action is to recurse or not. After all, that's why they have different types -- right?
To get rid of the dyn part, which is unnecessary, let's write a little generic helper function that uses XmlTagHandler to handle one specific kind of tag, and modify get_data_from so it just dispatches to the correct parameterized version of it. (I'll suppose that XmlTagHandler also has a new function so that you can create one generically.)
fn handle_tag<H: XmlTagHandler>(node: &Node) -> String {
let handler = H::new();
handler.foreach_child(node, |child| {
// do something with child value
});
handler.value()
}
fn get_data_from(node: &Node) -> String {
let tag_name = get_node_name(node);
match tag_name {
"name" => handle_tag::<NameHandler>(node),
"phone" => handle_tag::<PhoneHandler>(node),
_ => handle_tag::<DefaultHandler>(node),
}
}
If you don't like handle_tag::<SomeHandler>(node), also consider making handle_tag a provided method of XmlTagHandler, so you can instead write SomeHandler::handle(node).
Note that I have not really changed any of the data structures. Your presumption of an XmlTagHandler trait and various Handler implementors is a pretty normal way to organize code. However, in this case, it doesn't offer any real improvement over just writing three separate functions:
fn get_data_from(node: &Node) -> String {
let tag_name = get_node_name(node);
match tag_name {
"name" => get_name_from(node),
"phone" => get_phone_from(node),
_ => get_other_from(node),
}
}
In some languages, such as Java, all code has to be part of some class – so you can find yourself writing classes that don't exist for any other reason than to group related things together. In Rust you don't need to do this, so make sure that any added complication such as XmlTagHandler is actually pulling its weight.
is_recursive needs to be reimplemented to each struct because they traits cannot have field members, and I will have to add more fields later, which means more boilerplate for each new field
Without more information about the fields, it's impossible to really understand what problem you're facing here; however, in general, if there is a family of structs that have some data in common, you may want to make a generic struct instead of a trait. See the answers to How to reuse codes for Binary Search Tree, Red-Black Tree, and AVL Tree? for more suggestions.
I could use one type for a Handler and pass to it a function pointer, but this approach seems dirty
Elegance is sometimes a useful thing, but it is subjective. I would recommend closures rather than function pointers, but this suggestion doesn't seem "dirty" to me. Making closures and putting them in data structures is a very normal way to write Rust code. If you can elaborate on what you don't like about it, perhaps someone could point out ways to improve it.
I'm playing around with reactive flows using RxJava2, Micronaut and Cassandra. I'm new to rxjava and not sure what is the correct way to return a of List Person in the best async manner?
data is coming from a Cassandra Dao interface
public interface PersonDAO {
#Query("SELECT * FROM cass_drop.person;")
CompletionStage<MappedAsyncPagingIterable<Person>> getAll();
}
that gets injected into a micronaut controller
return Single.just(personDAO.getAll().toCompletableFuture().get().currentPage())
.subscribeOn(Schedulers.io())
.map(people -> HttpResponse.ok(people));
OR
return Single.just(HttpResponse.ok())
.subscribeOn(Schedulers.io())
.map(it -> it.body(personDAO.getAll().toCompletableFuture().get().currentPage()));
OR switch to RxJava3
return Single.fromCompletionStage(personDAO.getAll())
.map(page -> HttpResponse.ok(page.currentPage()))
.onErrorReturn(throwable -> HttpResponse.ok(Collections.emptyList()));
Not a pro of RxJava nor Cassandra :
In your first and second example, you are blocking the thread executing the CompletionStage with get, even if you are doing it in the IO thread, I would not recommand doing so.
You are also using a Single wich can emit, only one value, or an error. Since you want to return a List, I would sugest to go for at least an Observable.
Third point, the result from Cassandra is paginated, I don't know if it's intentionnaly but you list only the first page, and miss the others.
I would try a solution like the one below, I kept using the IO thread (the operation may be costly in IO) and I iterate over the pages Cassandra fetch :
/* the main method of your controller */
#Get()
public Observable<Person> listPersons() {
return next(personDAO.getAll()).subscribeOn(Schedulers.io());
}
private Observable<Person> next(CompletionStage<MappedAsyncPagingIterable<Person>> pageStage) {
return Single.fromFuture(pageStage.toCompletableFuture())
.flatMapObservable(personsPage -> {
var o = Observable.fromIterable(personsPage.currentPage());
if (!personsPage.hasMorePages()) {
return o;
}
return o.concatWith(next(personsPage.fetchNextPage()));
});
}
If you ever plan to use reactor instead of RxJava, then you can give cassandra-java-driver-reactive-mapper a try.
The syntax is fairly simple and works in compile-time only.
I've been searching for a function that takes an object of type Lock
and runs a block of code with that lock taking care of locking and also unlocking.
I'd implement it as follows:
fun <T : Lock> T.runLocked(block: () -> Unit) {
lock()
try {
block()
} finally {
unlock()
}
}
Used like this:
val l = ReentrantLock()
l.runLocked {
println(l.isLocked)
}
println(l.isLocked)
//true
//false
Anything available like this? I could only find the synchronized function which cannot be used like this.
You are looking for withLock, which has the exact implementation you've written yourself, except it has a generic parameter for the result of the block instead of the receiver type.
You can find other concurrency related methods of the standard library here, in the kotlin.concurrent package.
I have created a class in Typescript that implements a simple stream (FRP). Now I want to extend it with client side functionality (streams of events). To illustrate my problem, here is some pseudo-code:
class Stream<T> {
map<U>(f: (value: T) => U): Stream<U> {
// Creates a new Stream instance that maps the values.
}
// Quite a few other functions that return new instances.
}
This class can be used both on the server and on the client. For the client side, I created a class that extends this one:
class ClientStream<T> extends Stream<T> {
watch(events: string, selector: string): Stream<Event> {
// Creates a new ClientStream instance
}
}
Now the ClientStream class knows about map but the Stream class doesn't know about watch. To circumvent this, functions call a factory method.
protected create<U>(.....): Stream<U> {
return new Stream<U>(.....)
}
The ClientStream class overrides this function to return ClientStream instances. However, the compiler complains that ClientStream.map returns a Stream, not a ClientStream. That can be 'solved' using a cast, but besides being ugly it prevents chaining.
Example code that exhibits this problem:
class Stream {
protected create(): Stream {
return new Stream()
}
map() {
return this.create()
}
}
class ClientStream extends Stream {
protected create(): ClientStream {
return new ClientStream()
}
watch() {
return this.create()
}
}
let s = new ClientStream().map().watch()
This does not compile because according to the compiler, the stream returned from map is not a ClientStream: error TS2339: Property 'watch' does not exist on type 'Stream'.
I don't really like this pattern, but I have no other solution that is more elegant. Things I've thought about:
Use composition (decorator). Not really an option given the number of methods I would have to proxy through. And I want to be able to add methods to Stream later without having to worry about ClientStream.
Mix Stream into ClientStream. More or less the same problem, ClientStream has to know the signatures of the functions that are going to be mixed in (or not? Please tell).
Merge these classes into one. This is a last resort, the watch function has no business being on the server.
Do you have a better (more elegant) solution? If you have an idea that gets closer to a more functional style, I'd be happy to hear about it. Thanks!
What you're trying to do is called F-bounded polymorphism.
In TypeScript this is done via the this keyword. Take a look at Typescript's documentation for polymorphic this types. If you follow the documentation, you should be able to implement what you want :-)
Actually, just make sure that you're returning this in your member methods and you should be fine!