Vuex - How to handle large Data-Sets (Individual Load of Items) - vuex

Lets say we have a set of items, that is thousands of entries long.
It would not be practical to load all of them on page-load and have it in the store. How exactly would you deal with this?
Would you just add items to the store, that are actually requested?
What is the best practice here, if an item is not yet in the local store?
Lets say you are 'requesting' an item that is not yet in the local store (but would be available from the api), would you automatically try to retrieve it from the api before returning empty/an error?
Is there any best practice on how to implement this? It seems to be a pretty common use case.
Our should you just try to always load the whole data-set (or at least a minimal version) of it?
Also: what if the items change all the time (other users). Is there even a point in having those items in the store locally, if you need to request it again everytime you want to see its details to not get an outdated version?
Thanks

Related

Vue API Best Practice Duplicate Calls (Vuex?)

Within my app there are multiple pages that display a drop down of "clients". The select options are loading via an GET call made in Axios. Every time a page is displayed it makes that get call.
I'm curious if it's better to store those clients in Vuex, and then just load them that way so I don't make a call every time? The only thing I am concerned about is when a new "client" is added the best way to tell the app it needs to make a new get call to update the data in Vuex.
There are many possible solutions to this.
You could use a cache in back-end suchlike Redis, or as you said, cache it in the front-end.
You can abstract this caching with a get function which will check a maximum threshold of cache age.
For example, you can set it to last for 15 minutes. If another request is made before it you could answer with the last obtained data, else it will request the data to the server again.

Storing a list with React Native AsyncStorage: many keys or one?

I want to store a list of items with AsyncStorage. The list will be updated over time.
Here is an example of a state the list can be in:
[
{
name: "Alice",
email: "alice#example.com"
},
{
name: "Bob",
email: "bob#example.com",
address: "30 Madison Ave., NY"
}
]
Now, it seems that there are two options for storing this list:
Store each contact under its own key
Store the whole list under one key
There are advantages to either approach - what is preferred in React Native?
I think this depends on how you plan to use, access, and update the data. There are several asyncstorage methods you can use to help make either case easier.
If you decide to go the many keys route, have a look at multiSet and multiGet, which allows you to retrieve several keys in a single function call. And getAllKeys will save you the trouble of "keep[ing] track of all the keys you created", solving both of the problems mentioned by Fredrick Motte.
For updating many keys in one call, check out multiMerge which is a really powerful method, similar to mergeItem but multiple keys at once.
So, you see you can really go either route. If you divide your data up into multiple keys, then you'll probably just want to spend some time getting familiar with the methods I mentioned above.
And David's suggestion to give Relm a look might have some value for you as well, again... depending on your need.
For ease of use I'd store the list as a whole; since then you don't have to keep track of all the keys you created for each contact individually; and loading/saving them will be easier (just one function call instead of looping over all of your contacts).
But this is mostly a personal preference; there are no real constraints for any of the two methods.
I would add to the two good answers from Chris and Frederick:
it depends on the size of your list, and the size of your documents.
Going with one list as a whole is much easier to manage, but does not scale (computation will get heavier with the size of your global value).
going with one key per item adds some complexity but scales.
Personally I started with everything in one key, and now am refactoring to have one document per key, because when I'm processing hundreds of big documents, performances clearly degrade.
And if you are handling thousands or 10s of thousands of elements, I think you should go for a proper database like sqlite or realm (but debugging is an issue at the moment in realm).
Would be interested to know the true limits of asyncStorage, I read somewhere, it was a few megabytes unless you ask in your native config to increase it

SyncFolderItems - syncState size becomes huge! what can I do?

I am writing a mobile mail application and I am using the SyncFolderItems request to sync my folder.
The problem is, that when dealing with folders with a lot of items (e.g. 12000) the syncState becomes huge, and obviously this is not good for a mobile device..
Is there a workaround to this? Should I abandon the Sync operation and use pull subscriptions instead (And perhaps use findItem operation to get the initial id's? )
Thanks!!
What other people say, its a design question.
If you have a lot of e-mail, howmuch do you really need?
I mean, do i need 12000 items on my phone, i dont think so.
Good option is, save all the item id's with subject or something.
When click on the item, get the other properties. And don't save the information, it can be called from the Exchange Server...

How to decide whether to split up a VB.Net application and, if so, how to split it up?

I have 2 1/2 years experience of VB.Net, mostly self taught, so please bear with me if I seem rather noobish still and do not know some of the basics. I would recommend you grab a cup of tea before starting on this, as it appears to have got quite long...
I currently have a rather large application (VB.Net website) of over 15000 lines of code at the last count. It does not do retail or anything particularly complex like that - it is literally just a wholesale viewing website with admin frontend, catalogue / catalogue management system and pageview system.
I don't really know much about how .Net applications work in the background - whether they are all loaded on the same thread or if each has its own thread... I just know how to code them, or at least like to think I do... :-)
Basically my application is set up as follows:
There are two different areas - the customer area and the administration frontend.
The main part of the customer frontend is the Catalogue. The MasterPage will load a list of products but that's all, and this is common to all the customer frontend pages.
I tend to work on only one or several parts of the application at a time before uploading the changes. So, for example, I may alter the hierarchy of the Catalogue and change the Catalogue page to match the hierarchy change whilst leaving everything else alone.
The pageview database is getting really quite large and so it is getting rather slow when the application is first requested due to the way it works.
The application timeout is set to 5 minutes - don't know how to change it, I have even tried asking this question on here and seem to remember the solution was quite complex and I was recommended not to change it, but if a customer requests the application 5 minutes after the last page view then it will reload the application from scratch. This means there is a very slow page load whenever it exceeds 5 minutes of inactivity.
I am not sure if this needs consideration to determine how best to split the application up, if at all, but each part of the catalogue system is set up as follows:
A Manager class at the top level, which is used by the admin frontend to add, edit and remove items of the specified type and the customer frontend to retrieve a list of items of the specified type. For example the "RangeManager" will contain a list of product "Ranges" and will be used to interact with these from the customer frontend.
An Item class, for example Range, which contains a list of Attributes. For example Name, Description, Visible, Created, CreatedBy and so on. The form for adding / editing loops through these to display relevant controls for the administrator. For example a Checkbox for BooleanAttribute.
An Attribute class, which can be of type StringAttribute, BooleanAttribute, IntegerAttribute and so on. There are also custom Attributes (not just datatypes) such as RangeAttribute, UserAttribute and so on. These are given a data field which is used to get a piece of data specific to the item it is contained in when it is first requested. Basically the Item is given a DataRow which is stored and accessed by Attributes only when they are first requested.
When one item is requested from a specific manager is requested, the manager will loop through all the items in the database and create a new instance of the item class. For example when a Range is requested from the RangeManager, the RangeManager will loop through all of the DataRows in the Ranges table and create a new instance of Range for each one. As stated above it simply creates a new instance with the DataRow, rather than loading all the data into it there and then. The Attributes themselves fetch the relevant data from the DataRow as and when they're first requested.
It just seems a tad stupid, in my mind, to recompile and upload the entire application every time I fix a minor bug or a spelling mistake for a word which is in the code behind (for example if I set the text of a Label dynamically). A fix / change to the Catalogue page, the way it is now, may mean a customer trying to view the Contact page, which is in no way related to the Catalogue page apart from by having the same MasterPage, cannot do so because the DLL is being uploaded.
Basically my question is, given my current situation, how would people suggest I change the architecture of the application by way of splitting it into multiple applications? I mean would it be just customer / admin, or customer / admin and pageviews, or some other way? Or not at all? Are there any other alternatives which I have not mentioned here? Could web services come in handy here? Like split the catalogue itself into a different application and just have the masterpage for all the other pages use a web service to get the names of the products to list on the left hand side? Am I just way WAY over-complicating things? Judging by the length of this question I probably am, and it wouldn't be the first time... I have tried to keep it short, but I always fail... :-)
Many thanks in advance, and sorry if I have just totally confused you!
Regards,
Richard
15000 LOC is not really all that big.
It sounds like you are not pre-compiling your site for publishing. You may want to read this: http://msdn.microsoft.com/en-us/library/1y1404zt(v=vs.80).aspx
Recompiling and uploading the application is the best way to do it. If all you are changing is your markup, that can be uploaded individually (e.g. changing some html layout in an aspx page).
I don't know what you mean here by application timeout, but if your app domain recycles every 5 minutes, then that doesn't seem right at all. You should look into this.
Also, if you find yourself working on various different parts of the site (i.e. many different changes), but need to deploy only some items in isolation, then you should look into how you are using your source control tools (you are using one, aren't you?). Look into something like GIT and branching/merging.
Start by reading:
Application Architecture Guide

How to skip known entries when syncing with Google Reader?

for writing an offline client to the Google Reader service I would like to know how to best sync with the service.
There doesn't seem to be official documentation yet and the best source I found so far is this: http://code.google.com/p/pyrfeed/wiki/GoogleReaderAPI
Now consider this: With the information from above I can download all unread items, I can specify how many items to download and using the atom-id I can detect duplicate entries that I already downloaded.
What's missing for me is a way to specify that I just want the updates since my last sync.
I can say give me the 10 (parameter n=10) latest (parameter r=d) entries. If I specify the parameter r=o (date ascending) then I can also specify parameter ot=[last time of sync], but only then and the ascending order doesn't make any sense when I just want to read some items versus all items.
Any idea how to solve that without downloading all items again and just rejecting duplicates? Not a very economic way of polling.
Someone proposed that I can specify that I only want the unread entries. But to make that solution work in the way that Google Reader will not offer this entries again, I would need to mark them as read. In turn that would mean that I need to keep my own read/unread state on the client and that the entries are already marked as read when the user logs on to the online version of Google Reader. That doesn't work for me.
Cheers,
Mariano
To get the latest entries, use the standard from-newest-date-descending download, which will start from the latest entries. You will receive a "continuation" token in the XML result, looking something like this:
<gr:continuation>CArhxxjRmNsC</gr:continuation>`
Scan through the results, pulling out anything new to you. You should find that either all results are new, or everything up to a point is new, and all after that are already known to you.
In the latter case, you're done, but in the former you need to find the new stuff older than what you've already retrieved. Do this by using the continuation to get the results starting from just after the last result in the set you just retrieved by passing it in the GET request as the c parameter, e.g.:
http://www.google.com/reader/atom/user/-/state/com.google/reading-list?c=CArhxxjRmNsC
Continue this way until you have everything.
The n parameter, which is a count of the number of items to retrieve, works well with this, and you can change it as you go. If the frequency of checking is user-set, and thus could be very frequent or very rare, you can use an adaptive algorithm to reduce network traffic and your processing load. Initially request a small number of the latest entries, say five (add n=5 to the URL of your GET request). If all are new, in the next request,
where you use the continuation, ask for a larger number, say, 20. If those are still all new, either the feed has a lot of updates or it's been a while, so continue on in groups of 100 or whatever.
However, and correct me if I'm wrong here, you also want to know, after you've downloaded an item, whether its state changes from "unread" to "read" due to the person reading it using the Google Reader interface.
One approach to this would be:
Update the status on google of any items that have been read locally.
Check and save the unread count for the feed. (You want to do this before the next step, so that you guarantee that new items have not arrived between your download of the newest items and the time you check the read count.)
Download the latest items.
Calculate your read count, and compare that to google's. If the feed has a higher read count than you calculated, you know that something's been read on google.
If something has been read on google, start downloading read items and comparing them with your database of unread items. You'll find some items that google says are read that your database claims are unread; update these. Continue doing so until you've found a number of these items equal to the difference between your read count and google's, or until the downloads get unreasonable.
If you didn't find all of the read items, c'est la vie; record the number remaining as an "unfound unread" total which you also need to include in your next calculation of the local number you think are unread.
If the user subscribes to a lot of different blogs, it's also likely he labels them extensively, so you can do this whole thing on a per-label basis rather than for the entire feed, which should help keep the amount of data down, since you won't need to do any transfers for labels where the user didn't read anything new on google reader.
This whole scheme can be applied to other statuses, such as starred or unstarred, as well.
Now, as you say, this
...would mean that I need to keep my own read/unread state on the client and that the entries are already marked as read when the user logs on to the online version of Google Reader. That doesn't work for me.
True enough. Neither keeping a local read/unread state (since you're keeping a database of all of the items anyway) nor marking items read in google (which the API supports) seems very difficult, so why doesn't this work for you?
There is one further hitch, however: the user may mark something read as unread on google. This throws a bit of a wrench into the system. My suggestion there, if you really want to try to take care of this, is to assume that the user in general will be touching only more recent stuff, and download the latest couple hundred or so items every time, checking the status on all of them. (This isn't all that bad; downloading 100 items took me anywhere from 0.3s for 300KB, to 2.5s for 2.5MB, albeit on a very fast broadband connection.)
Again, if the user has a large number of subscriptions, he's also probably got a reasonably large number of labels, so doing this on a per-label basis will speed things up. I'd suggest, actually, that not only do you check on a per-label basis, but you also spread out the checks, checking a single label each minute rather than everything once every twenty minutes. You can also do this "big check" for status changes on older items less often than you do a "new stuff" check, perhaps once every few hours, if you want to keep bandwidth down.
This is a bit of bandwidth hog, mainly because you need to download the full article from Google merely to check the status. Unfortunately, I can't see any way around that in the API docs that we have available to us. My only real advice is to minimize the checking of status on non-new items.
The Google API hasn't yet been released, at which point this answer may change.
Currently, you would have to call the API and dis-regard items already downloaded, which as you said isn't terribly efficient as you will be re-downloading items every time, even if you already have them.