Android-cleanarchitecture: How to introduce network-dependent push notification while `Repository` hide network details?

Created on 31 May 2016  Â·  5Comments  Â·  Source: android10/Android-CleanArchitecture

My app allows background request to network, but only one at the same time.

I need to do two things:

  1. Limit one request at the same time
  2. Notify user via push-notification about currently executing request

My problem is that Repository caches data and hides the network details from any other layer.

I see the solution in creating&injecting EventBus through whole application's layers and posting "RequestStarted"/"RequestFinished" events. Then, handle it on Presentation layer and create new push-notification.

About limitation. For example, I can create class RequestLimitator { boolean isBusy; } and inject it to Cloud***DataStores, then change isBusy and throw NetworkIsBusyException to handle it in Presentation layer.

Is it true way to do things? :)

Most helpful comment

@Try4W Be very careful with EventBus, I have bad experience of using it. Firstly it may seem awesome and useful tool, but do not use it too much. Think twice before using EventBus. IT IS VERY DIFFICULT TO DEBUG EVENTS.

In your case using it for notifications may be good choice, but also have a look at RxJava it may satisfy your requirements.

My applications currently is not built according Clean Architecture principles and I use EventBus in following case.

Firstly when user requests some data, data is taken from local storage after returning data back to user , request to the server is made and when request result comes back it checks if data on the server has changed or not in case new data is available EventBus throws notification and Fragment listens for this event and displays notification that new data is available : "Swipe to refresh". ( I am going to write an article about this soon)

I think this is possible way, but in case of EventBus application architecture is more Bus than Layered .

All 5 comments

@Try4W Be very careful with EventBus, I have bad experience of using it. Firstly it may seem awesome and useful tool, but do not use it too much. Think twice before using EventBus. IT IS VERY DIFFICULT TO DEBUG EVENTS.

In your case using it for notifications may be good choice, but also have a look at RxJava it may satisfy your requirements.

My applications currently is not built according Clean Architecture principles and I use EventBus in following case.

Firstly when user requests some data, data is taken from local storage after returning data back to user , request to the server is made and when request result comes back it checks if data on the server has changed or not in case new data is available EventBus throws notification and Fragment listens for this event and displays notification that new data is available : "Swipe to refresh". ( I am going to write an article about this soon)

I think this is possible way, but in case of EventBus application architecture is more Bus than Layered .

@CROSP EventBus may be a tricky solution, yeah.

I think this is possible way, but in case of EventBus application architecture is more Bus than Layered.

Yep. And following CA philosophy there is only one way to share data "from the bottom" — stream. But I can't imagine any nice way to notify Presentation layer about different requests started/finished via Observable.
diagram

As an alternative, I can manage limitation on Domain layer than Data layer. Request limitation isn't business logic? Or it is? :)
But if I want — I can't. As the network is hidden by Repository.

In my case, every request is started by clicking on a button. It means that I can call notification directly on Presentation layer.

There is some my "pseudo-code".

class AddCarToQueuePresenter {

    RequestNotificatorService notificator; // injected by Dagger 2

    void addCar(CarInQueue car) {
        notificator.showAddCarToQueueRequestStartedNotification();
        addCarToQueue.setup(car).execute(result -> {
                notificator.show();
                // process result
            }, throwable -> {
                handleError(throwable);
            }, () -> {
                notificator.hideNotification();
                // on completed
            }):
    }

    void handleError(Throwable throwable) { // in super class
        if(throwable instanceof NetowrkIsBusyExeption) {
            // show network is busy error
        } else if(throwable instanceof NetworkException) {
            // show no network error
        }
    }

}

I finally lost :c

Okay. I think a little bit and came up to the main question:
RequestLimitator — is it related to Data layer, or Domain?

As I see it at now:
RequestLimitator — class that gives answers to questions like "can I execute this request?"

For example: user click Button "DoThing" -> DoThingPresenter execute DoThingUseCase -> DoThingUseCase call ThingsRepository -> ThingsRepository call ThingsDataStore -> _(and if ThingsDataStore is Cloudy)_ -> call RequestLimitator.canPerformRequest() _(and if it can)_ -> post DoThingRequestStartedEvent by EventBus
_pew!_
PresentationLayer handle DoThingRequestStartedEvent

Sorry for late response.
As I can guess RequestLimitator is used for limit amount of request coming from UI layer when user clicks button, and you need this limitator in order to limit request that are sent directly directly to the server ?
If so, first question is :
Is this logic is core of your app ? what does this mean ? If you have application and its main feature to limit request that this should go to the Domain/Use Case layer, because this is core of your app and you are going to implement this on any platform you are going to port your app.

On the other hand if you need just limit request for saving bandwidth and server load than this is probably should go to the Data Layer and you also free to do tricks like returning cached value from this layer or just throw exception if amount of requests exceeds the limit .

What about EventBus and RxJava for communication between layers.
You are not obliged to use RxJava this is just author proposition and point of view. You can use anything that suits better for your purposes.

I must limit count of requests directly to the server as my app will be used in areas with an unstable internet connection. It's the main feature, but in the same time it low-level enough to be placed in Data Layer as at Domain Layer I don't know what data store are used to get data.

I decided to place this functionality in Data Layer and I hope that this is not a mistake :)
Thanks for you help&explanations.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fabius-bile picture fabius-bile  Â·  5Comments

Cook1 picture Cook1  Â·  4Comments

Deep21 picture Deep21  Â·  6Comments

ashraffouad picture ashraffouad  Â·  5Comments

donlucard picture donlucard  Â·  3Comments