Synchronizing high scores between local and server using RxJava

I am trying to sync some data between local records and records on the server.   syncList

is the entry point for the synchronization operation with local records. Inside this method, I call a method syncResultObservable

that returns an Observable with records on the server.

After downloading the records from the server, I use flatmap

to convert the sync result to map<String, List<String>>

by calling syncResult (List<String> local, List<String> server)

. The resulting map

should have 2 keys  "toAdd":List<String>

 "toRemove":List<String>

Now I want to perform separate operations on each result. recordsAddObservable

should add a list from toAdd

(i can do that). recordsRemoveObservable

should remove add list from toRemove

(could not find a way to perform this operation using the same observable).

recordsAddObservable

The operation toAdd

works fine for me. However, I'm trying to find a way to call recordsRemoveObservable

on the map result without forcing the entire sync operation to run again to remove the case. Below is a small snippet for 'toAdd' entries.

public void syncList(final List<String> localData) {
   //fetch the server data
    Observable<Map<String, List<String>>> syncResultObservable = serverDataDownloadObservable(userid)
            .flatMap(new Func1<String[], Observable<Map<String, List<String>>>>() {
                @Override
                public Observable<Map<String, List<String>>> call(String[] serverData) {
                    Map<String, List<String>> map = syncResult(localData, Arrays.asList(serverData));
                    return Observable.just(map);
                }
            });

    syncResultObservable.flatMap(new Func1<Map<String, List<String>>, Observable<List<String>>>() {
        @Override
        public Observable<List<String>> call(Map<String, List<String>> stringListMap) {
            List<String> toAdd;
            toAdd = stringListMap.get("toAdd");
            if (toAdd == null || toAdd.isEmpty()) {
                toAdd = new ArrayList<String>();
            }
            return Observable.just(toAdd);
        }
    }).flatMap(new Func1<List<String>, Observable<Result>>() {
        @Override
        public Observable<Result> call(List<String> strings) {
            if (strings.isEmpty() == false) {
                String[] toAdd = strings.toArray(new String[strings.size()]);
                Log.i(LogEnum.LogPriority.info, getClass, "syncRecords: will try to add records ", toAdd);
                return apis.recordsAddObservable(userid, toAdd);
            }
                Log.i("Tag", getClass, "syncRecords: no records to add, toAdd);

            Log.i("Tag", getClass, "syncRecords: no records need to be added ");
            return Observable.just(new Result(null, null));
        }
    }).subscribeOn(Schedulers.io()).subscribe(new Subscriber<Result>() {
        @Override
        public void onCompleted() {
             //
        }

        @Override
        public void onError(Throwable e) {
        }

        @Override
        public void onNext(Result result) {
            onCompleted();
        }
    });
}






public Map<String, List<String>> syncResult (List<String> local, List<String>  server) {
    . . .
    . . .

    Map<String, List<String>> map = new HashMap<>();
    map.put("toAdd", toAddList);
    map.put("toRemove", toRemoveList);
    return map
}

      

Please let me know if there is an easy way to make individual work of different result sets.

Thanks Big O

+3


source to share


2 answers


This is how I solved it.



public void syncList(final List<String> localData) {
   //fetch the server data

         Observable<Map<String, List<String>>> syncResultObservable = serverDataDownloadObservable(userid)
        .flatMap(new Func1<String[], Observable<Map<String, List<String>>>>() {
            @Override
            public Observable<Map<String, List<String>>> call(String[] serverData) {
                Map<String, List<String>> map = syncResult(localData, Arrays.asList(serverData));
                return Observable.just(map);
            }
        }).subscribeOn(Schedulers.io())
            .subscribe(new Action1<Map<String, List<String>>>() {
                @Override
                public void call(Map<String, List<String>> stringListMap) {
                    List<String> toAdd = stringListMap.get("toAdd");
                    if (toAdd != null && toAdd.isEmpty() == false) {
                    } else {
                        addRecords(toAdd);
                    }
                    List<String> toRemove = stringListMap.get("toRemove");
                   if (toRemove != null && toRemove.isEmpty() == false) {
                        removeRecords(toRemove);
                    }
                }
            });

}

      

+1


source


Here's an example that I think does what you want:



  • takes a stream of local and server values,
  • apply a list to them,
  • write them together and apply the difference calculation logic,
  • since you decided to use a map with specific keys, we need to flatten it into streams with keys,
  • then create groups based on two keys,
  • and switch the keys to flatMap to run the asynchronous work needed for each case.
+1


source







All Articles