Resource management

Resource management, what does it mean? Why should we care about it? If you've a little experience in application development with Java,Kotlin,JavaScript, or any other language, then you're probably familiar with the fact that while developing applications, we often need to access resources, and we must close them when we are done.

If you're not experienced with that phrase, resource management, then let's break things down. We will be starting from the ground by exploring the definition of a resource.

So, what is resource? When developing applications, you may often need to access an API (through an HTTP connection), access a database, read from/write to a file, or you may even need to access any I/O ports/sockets/devices. All these things are considered resources in general.

Why do we need to manage/close them? Whenever we are accessing a resource, especially to write, the system often locks it for us, and blocks its access to any other program. If you don't release or close a resource when you're done, system performance may degrade and there may even be a deadlock. Even if the system doesn't lock the resource for us, it will keep it open for us until we release or close it, resulting in poor performance.

So, we must close or release a resource whenever we are done working with it.

Generally, on the JVM, we access resources through a class. Often, that class implements the Closable interface, making releasing a resource easy for us by calling its close method. It's quite easy in imperative programming, but you're probably wondering how to do it in reactive programming.

You're probably thinking of mixing imperative programming with reactive programming and making the resources global properties, and then, inside the subscribe method, you'll dispose them after using. This is basically what we did in Chapter 5
Asynchronous Data Operators and Transformations HTTP Request.

Sorry to break your heart, but that is the wrong procedure; in Chapter 5
Asynchronous Data Operators and Transformations, we did it to avoid further complexities in order to make you understand the code better, but we should learn the correct approach now.

To make things less complex, we will create a dummy resource with a custom implementation of the Closable interface. So, no more suspense; take a look at the following code snippet:

    class Resource():Closeable { 
      init { 
        println("Resource Created") 
      } 
 
      val data:String = "Hello World" 
 
      override fun close() { 
        println("Resource Closed") 
      } 
    } 

In the preceding code, we created a Resource class and implemented Closeable in this class (just to mock a typical Java resource class). We also created a val property named data inside that class, which will be used to mock data fetching from Resource.

Now, how do we use it in a reactive chain? RxKotlin provides a very convenient way to deal with disposable resources. To save your life with disposable resources, RxKotlin has a gift for you—the using operator.

The using operator lets you create a resource that'll exist only during the life span of the Observable, and it will be closed as soon as the Observable completes.

The following diagram describes the relation of lifespans of Observable created with the using operator and the resource attached to it, which has been taken from ReactiveX documentation (http://reactivex.io/documentation/operators/using.html):

The preceding image clearly displays that the resource will live during the lifespan of the Observable only—a perfect life partner, wouldn't you say?

Here is the definition of the using operator:

    fun <T, D> using(resourceSupplier: Callable<out D>, sourceSupplier:    
Function<in D, out ObservableSource<out T>>,
disposer: Consumer<in D>): Observable<T> { return using(resourceSupplier, sourceSupplier, disposer, true) }

It looks confusing, but it's easy when we break it down. The using method accepts a Callable instance, which will create a resource and return it (out D is for that purpose). And, the last one is to release/close the resource. The using operator will call the first lambda before creating the Resource instance. Then, it'll pass the Resource instance to the second lambda for you to create Observable and return it so that you can subscribe. Finally, when the Observable calls its onComplete event, it will call the third lambda to close the resource.

You're now dying to see the example, right? The following is the example:

    fun main(args: Array<String>) { 
      Observable.using({//(1) 
        Resource() 
      },{//(2) 
        resource:Resource-> 
        Observable.just(resource) 
      },{//(3) 
        resource:Resource-> 
        resource.close() 
      }).subscribe { 
        println("Resource Data ${it.data}") 
      } 
    } 

In the preceding program, we passed three lambdas to the using operator. In the first lambda (comment one), we created an instance of Resource and returned it (in a lambda, the last statement works as return, you don't have to write it).

The second lambda will take resource as parameter and will create the Observable from it to return.

The third lambda will again take resource as a parameter and close it.

The using operator will return the Observable you created in the second lambda for you to apply the RxKotlin chain to it.

So, here is a screenshot of the output, if you're curious:

So, that is resource management made easy. Also note that you can create and pass as many resources as you want to the using operator. We implemented the Closable interface for ease of understanding, but it's not mandatory; you can easily create and pass an array of resources.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.186.178