Closed Lavanyagaur22 closed 5 years ago
Generic Mutation is the class we build for our stored mutation objects.
@harshithdwivedi @wtrocki Let me know what do you think about this?
When we are offline, in case of any mutation made by the user, Apollo will throw a network exception and in onFailure() we'll store the mutation object in the queue.
We have Network monitors implemented in our app, when the client comes online we will fetch the stored mutation one by one. With the mutation fetched we again make a network call with the Apollo client. But in the enqueue method, we will have to pass something
We can simply have 2 callbacks, one for offline error and another for success.
The main problem of offline support is that it is going to change the workflow. This cannot be avoided as when we enqueue data in some storage users can navigate off the view. This means that we cannot avoid having this non UI bound processing that users can hook into thru listeners.
Suggested approach:
Return error on the first pass and for second enqueue ignore the UI binding - This means that problem with the second enqueue is not a problem as we do not need to read returned object. Our generics could be simply
@Lavanyagaur22 If you can check if it will be possible to use an object on enqueue.
It will be nice to create second issue for offline listener to start discussing how this could look like - what type of events we look for and what interface we are going to use .
Okay, so you mean that trying for an enqueue method for an object without any callbacks. So, in that case, we don't want any class in client.enqueue to which data would be matched. With that method, we would just be hitting mutations to the server when the client comes online.
@wtrocki Let me research and check on this.
In this case data will be passed to listener and then users can cast the objects like suggested in #30
We cannot avoid casting unless we want to use reference and store class names in the database (probably not the best idea)
@Lavanyagaur22 If you can check if it will be possible to use an object on enqueue.
@wtrocki yeah, I checked this is possible.
I have used an ArrayList (of Type
I have made an interface CustomApolloCall which extends ApolloCall and in its Enqueue and Callback method passed Void as a generic type.
In MainActivity, I have an offOn Button (for spike), clicking on which fetches mutation object from the list and make a call to the server and the cache is updated with subscriptions received.
I have deleted the mutation object which has been replicated to the server in OnResponse() method of callback (which here is not returning the data).
When I updated Task 7 from version 3->4.
The in-memory part can be done by storing mutation object in ArrayList (will work when the app is in foreground). Now, when the app is killed, for that part we need to store mutation in a database.
@wtrocki Can I resume researching On the GenericMutation part I was working on earlier.
GenericMutation class will extend the mutation interface and we will try to make this in such a way that when we come online, we make an object of this class, make a server call but we don't listen for any response from the server, because of mapping of data can cause many class cast exceptions.
@wtrocki @harshithdwivedi If in our approach of making a Generic class and passing an object of that class to the server call, what we can do is not listen to the response returned back from the server ( which comes in Operation.Data ). We can use subscriptions, in this way some class cast exceptions can be avoided. WDYT?
Hm interesting. When the user is offline, we don't need the UI Bindings anyways, good thinking!
@wtrocki what do you think?
On Thu, Jun 27, 2019, 4:38 PM Lavanya gaur notifications@github.com wrote:
@wtrocki https://github.com/wtrocki @harshithdwivedi https://github.com/harshithdwivedi If in our approach of making a Generic class and passing an object of that class to the server call, what we can do is not listen to the response returned back from the server ( which comes in Operation.Data ). We can use subscriptions, in this way some class cast exceptions can be avoided.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/aerogear/offix-android/issues/29?email_source=notifications&email_token=ALLWCVEJRABR67LDMJOHBMLP4SNS3A5CNFSM4H23RSS2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODYWY6UY#issuecomment-506302291, or mute the thread https://github.com/notifications/unsubscribe-auth/ALLWCVFTXM2E4D262FK66ODP4SNS3ANCNFSM4H23RSSQ .
Yes this is great idea. We will still need to listen - in order to notify listeners but we do not care about the data and people can cast objects if they need it in listeners. So if we can use Object as generic is fine. Alternative will be to use java reflection and fully classified class names, but that seems to be overkill for that use case.
+1, for initial milestone; let's go with providing the result as Object and once that's done, we can probably think about reflection and genetics.
On Thu, Jun 27, 2019, 5:03 PM Wojtek Trocki notifications@github.com wrote:
Yes this is great idea. We will still need to listen - in order to notify listeners but we do not care about the data and people can cast objects if they need it in listeners. So if we can use Object as generic is fine. Alternative will be to use java reflection and fully classified class names, but that seems to be overkill for that use case.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/aerogear/offix-android/issues/29?email_source=notifications&email_token=ALLWCVGKYBAK2FFL5L3Z3CLP4SQQPA5CNFSM4H23RSS2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODYW2UVI#issuecomment-506309205, or mute the thread https://github.com/notifications/unsubscribe-auth/ALLWCVDPOBVNRD335PUIKE3P4SQQPANCNFSM4H23RSSQ .
Yes. We are really close to have this end to end which is sooo awesome. Let's not try to get things overly complex from the start. Once we have working prototype we can think about limitations and how we can move from there.
At this point I'm more concerned about listeners. In Java land global listeners to the data are very rare thing so we might need to figure a way to make them work as normal java dev will expect them to work.
Description
When the user is offline, mutations should be stored in an offline queue so that when the network comes all the stored mutations can be replicated back to the server and user can have the latest fresh data.
This can be divided into two parts:
1. In-memory storage of mutations
We can build an ArrayList or a queue which will store all the mutation object. When the network comes we can pop the mutations one by one and make a call to the server and when this is successfully done we can delete that mutation from the arraylist/queue.
This will work only when the application is in the foreground, if the app is killed the stored mutation object would be lost, so it would be better if we can store mutation object in the database (approaches on the restoration of mutation object from DB needs to be discussed).
Problem:
When we pop a mutation object from the list and try to make a network call to the server, then the "enqueue" method of Apollo client needs a class to which the data sent from the server can be mapped to, for example (from sample):
client?.enqueue(object : ApolloCall.Callback<UpdateCurrentTaskMutation.Data>()
UpdateCurrentTaskMutation is the class for update mutation to which data sent from the server is mapped to. So here which class we will use? We need to create our own class for the Callback method which will have to implement Data interface for letting it know that the response has to be matched to this class.2. Database approach
We can make a database which can store mutation data and variables, operation id and some important info about that particular mutation like this:
Then we can make a generic class, for example, GenericMutation class which will extend the mutation interface and we will try to make this in such a way that when we come online, we make an object of this class, make a server call and the response can also be mapped to this class.
What we do:
This commit contains the things added for the above implementation.
https://github.com/aerogear/offix-android/pull/27/commits/51c7a5710010c6088e5f3e939d2ab7c4b53e959b
Problem: