Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Managing remote service callbacks

I have a situation where I feel like I'm about to reinvent the wheel or go around the houses, to handle something that there is already a 'design' for - so before I do, I was hoping I could get a second opinion please.

I have a remote service. It is a permanent foreground service due to the unusual nature/functionality of the application itself.

I'm writing a library so that third party applications can bind to the service and use the APIs I expose. As I'm handling the threading myself and most of the callbacks will be of an asynchronous nature, I'm using an AIDL approach, with custom classes that are 'Parcelled up' to provide the necessary parameters to the Service. Everything thus far, is working perfectly.

The construct of my Service code is very similar to the RemoteService API example, so I'll refer to that, as posting my specific code does not alter the question.

As with the example, the Interface of each request I save into a RemoteCallbackList, which appears to be a handy solution to some other fundamentals.

However, my Service does not provide the same information to a group of 'waiting receivers' as the use of the following snippet demonstrates:

 int i = callbacks.beginBroadcast();
 while (i > 0) {
     i--;
     try {
         callbacks.getBroadcastItem(i).somethingHappened();
     } catch (RemoteException e) {
         // The RemoteCallbackList will take care of removing
         // the dead object for us.
     }
 }
 callbacks.finishBroadcast();

Instead, the requests are of many different types and therefore I need to keep track of which exact Interface object I am to send results back to. Each individual request may involve further asynchronous web requests and/or processing and having to hand around the callback object to each of these (either via a constructor or just a method parameter) is where I feel I'm about to do something very tedious and long-winded to solve a problem that I can perhaps simplistically achieve another way?

The task would be made easy if I could guarantee that the first request in, would be the first result out and therefore simply use the order in the RemoteCallbackList before removing reference to them, but this is not the case, due to the varying processing times of the different request types.

Edit - It appears the RemoteCallbackList is backed by an ArrayMap and so I believe not ordered anyway?

I can find no documented way of narrowing down where the callback in the RemoteCallbackList originated, although even if I could, I would of course still need some kind of persistent identifier to know what I was looking for.... Stumped.

Thanks for reading this far, any ideas are welcome.

Edit - For the purpose of pseudo example. Imagine the API requests are about books.

// requests
bookExists(String title)
bookContent(String title)

// response
bookExists(boolean exists)
bookContent(ArrayList<String> words, int pageTotal)

As you can see from the above, all things being equal, a remote request for a smaller book or the existence of a book, may complete and be ready to respond prior to a request for a longer book, even if it was requested after. This is where I need to track the 'requester' and is the design I'm after.

like image 554
brandall Avatar asked Mar 01 '16 21:03

brandall


1 Answers

If I understood you right, all that you have to do is to respond to your requests from the RemoteCallbackList using the same interface, but with different responding data structures.

I guess, the most simple way is to make the requests to bring you info what kind of returning data structure they want. The most obvious (maybe even stupid) way - is to send you the name of class you have to instantiate and fill in. In more sophisticated way you may just create some enumeration which item name should be brought by request and which will define the proper data structure class to be instantiated and returned.

The second way is to have some kind of response resolver - some logic that will detect what kind of data the request may want. But IMHO it looks too ambiguous, quite complicated and not very convenient to support.

Anyway - it is quite doubtful you will find some universal solution for such a case, because it is not a common one.

Hope this helps.

like image 150
domax Avatar answered Oct 24 '22 09:10

domax