Push vs Pull: air conditioning system

By Ivan Morgillo, Sasa Sekulic and Fabrizio Chignoli

This article has been excerpted from Grokking ReactiveX.

After a life of imperative programming, switching to a reactive mindset could seem challenging:

“Why should I give up all the control and bend to this <data are in control> thing?”

Let’s look at it in an everyday life scenario: the air conditioning system. Today is a hot day and we want to start the AC system when the temperature in the room reaches 77F. We need a thermometer.


Well, we need a Thermometer class that provides a temperature() method to obtain the current temperature in the room.

Once we know how to obtain the current temperature, we can combine it with our AirConditioning class.

This class provides three methods:

class AirConditioning {
start()
stop()
isRunning()
}

To change the status of the air conditioning system, we can use start() and stop(). If we want to check if the status change was successful, isRunning() gives us info about the current status.

Now that we know the current temperature with temperature() and we can turn on the Air Conditioning system with start(), we can create an AirConManager class with a basic monitor() method that will contain the logic needed to retrieve the current temperature, evaluate a condition and execute the proper action:

fun monitor() {
while (true) {
if (thermometer.temperature() >= 77 && !ac.isRunning()) {
ac.start()
break;
}
}
}

The current implementation of the monitor() function is almost offensive and I will understand if your eyes start bleeding:

  • we have a while(true) loop to keep on evaluating the condition;
  • we have the if condition itself that retrieves the current temperature, checks if it’s lower than 77 degrees and if the Air Conditioning system is already on;
  • we have the action block that starts the Air Conditioning system and ends the loop.

So far, we don’t have any special requirements and we don’t care about details like stopping the system or restarting the loop if the temperature drops.

This function could be refactored and polished in a few ways, but the key point will still be:

Constantly checking the temperature and deciding what to do accordingly


How could we migrate to a reactive scenario?

In an Rx oriented scenario, our thermometer would be an observable thermometer, represented by an ObservableThermometer class.

The ObservableThermomenter class will provide a single method: rxTemperature(). If we subscribe to this Observable we’ll receive the current temperature every time it changes:

fun rxTemperature() : Observable<Int> {
[...]
}

We can go back to our AirConManager and refactor it to handle out new reactive thermometer.

AirConManager can subscribe to ObservableThermometer in its monitor() method and receive a new temperature value:

void monitor() {
rxTemperature()
.subscribe(temperature -> {
if (temperature >= 77 &&!ac.isRunning()) {
ac.start()
}
})
}

Note: This .subscribe() method has a Subscriber implementing the onNext() method as a lambda expression. Subscribers usually have three methods, but if you don’t need to be notified when the stream completes or you don’t want to manage possible error scenarios, you can avoid implementing onCompleted() and onError().

The moment we subscribe, the data will start coming to us: the onNext() will receive a temperature value, we’ll evaluate it and act accordingly.

“Wait a second! All this fuss to save me a while loop?”

One of the key principles of reactive programming is that it is all about data being in charge, being able to create the perfect data stream you need and working with the stream that is available.

Let me introduce you to the .filter() operator!

Push vs Pull: create the flow you need

In our scenario, we don’t need a temperature value every time it changes. We just need to know when the temperature reaches 77F to start the Air-conditioning system. Rx is all about flowing data, coming to us to be used, filtered and transformed.

Let’s improve our monitor() method to create the sequence we need by filtering out all the temperature values we don’t need:

fun monitor() {
rxTemperature()
.filter(!ac.isRunning)
.filter(temperature >= 77)
.subscribe(temperature -> ac.start())}

As you can see, filter() evaluates a Predicate and propagates the item only if the condition is satisfied.

We were supposed to receive a new temperature value in our onNext() every second, but what we wanted was instead to get into the game only if the Air Conditioning system was off and the temperature in the room was higher than 77F. We used filter() to filter out all those scenarios we weren’t interested in and receive only the values that match our use case. We created the perfect sequence for the task at hand from an initial generic sequence that we can’t control.

This is the power of the Push approach: data coming to us. We can focus on using the data instead of retrieving and managing them.

If you’re interested in learning more, download the free first chapter of Grokking ReactiveX and see this Slideshare presentation for more details and a discount code.

If you enjoyed this article, please click the 💚 below and spread the Rx love 😊

2015: my quantum leap

First week of 2016, lots to do, but what about 2015?

I’m still working remotely and this helped a lot from a logistic point of view: I relocated in France with my fiancee.

Writing

I started this blog and I’m putting a fair amount of energy into it, but the most important event is definitely the publication of my first book: RxJava Essentials (https://www.packtpub.com/application-development/rxjava-essentials). It was a big achievement for me. I’m very fond of the reactive approach and I have spent 2013 and 2014 talking to people, trying to help them overcoming their “fear” of this paradigm. But it was just “talking”. When Packt Publishing gave me the opportunity to “write” about Rx in a very similar way I was “talking” about Rx, I jumped on it.

Talking

I was very focused on the book and I completely missed the deadline for Droidcon Turin in April. I didn’t want to lose the chance to challenge myself and I arranged a quick barcamp session when I was there. First time talking to an unknown crowd: my “lizard-people-person” instinct kicked in and they almost had to put me down after one hour talking and showing code.

In June, I had my first Droidcon talk in Berlin:

I was super nervous, there were tons of people and when the staff started to add even more chairs for the audience… I almost freaked out! The talk went well, people enjoyed it and I had lots of feedback. I can proudly say that’s the most popular DroidconDE video, so far.

In November, I had my first Devoxx talk in Antwerp. Great experience! I wrote a post about it and you can check it out here: https://medium.com/@hamen/my-first-devoxx-fd82ee7d476c#.1iv2ynrzy

In December, I was in Krakow for my talk at the Droidcon, back in Poland after ten years. You can read my report here: https://medium.com/@hamen/back-in-krakow-for-the-droidcon-25f5b868a981#.v5oyznyg7

Conference after conference, I thought I would be less nervous. Not really. You are surely more confident, but you are still nervous, because you want to share knowledge, because you don’t want to disappoint people, because you care!

2016?

Well, the journey continues: more code, more books, more talks, more friends. See you there 😉

Back in Krakow for the Droidcon


After almost ten years, I was in Poland again last week. Ten years ago I was an Erasmus student; last week I was a speaker at Droidcon Krakow!

The venue

Every Droidcon feels like a family reunion to me, but the funny part is that the family is continuously growing in size, every time we meet.

Droidcon Krakow venue was a hotel and turns out that’s just brilliant: everything is already there, organised, comfortable. The food was really good and those “always-on” buffets were delicious. I stayed in the same hotel and this made the logistics as smooth as possible.

The tech stuff

Talks and speakers were awesome. I met a few friends from my first Droidcon in Berlin and tons of new nerds, curious and ready to learn and share .

Chatting with people and attending the talks, I noticed a few strong trends:

  • Reactive Programming is growing on the community. Both talks, mine and Sasa Sekulic‘s were sold out. There is definitely less fear and more desire to evolve.


  • Testing is easier now and higher code quality is the final goal for a lot of developers, no matter what; developers cannot stand anymore to work on badly designed, untestable apps.
  • Kotlin could be the next big thing, but everybody is very skeptical about Google officially supporting it; we all hope that at some point, everybody will realise that Java 1.6 is “obsolete” for 2016 mobile development.

  • Nobody is using G+. Apparently, everybody is using Twitter, even in the Android ecosystem.

Media

My slides, both Keynote and PDF format, and the example source code are here:

https://github.com/hamen/rxjava-essentials/tree/master/slides/droidcon.pl

Conclusions

I definitely enjoyed Droidcon Krakow and I’m looking forward to the next year.