-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Of identifying the array responses' items #983
Comments
The OpenAPI Schema spec doesn't provide an explicit provision for tagging unique fields (although you can tag an array as having unique items). It is possible to extend the spec similar to HTTP header conventions, e.g. x-your-custom-tag. So CCP would have to choose to do that. I have a similar problem for EveKIt. I've discovered unique fields for all the ESI data I store through hard fought trial/error and asking questions. Depending on how you "flatten" your data, uniqueness only comes in some cases by combining multiple fields into a composite key. I'm happy to document my list of unique keys somewhere if that's helpful. |
Please document your findings! |
@deadlybulb thank you very much, that covers my question with sourced informations. @EricE what do you mean ? |
@guiguilechat sorry I wasn't clearer. Comment was for @deadlybulb in response to the last sentence of his post, "I'm happy to document my list of unique keys somewhere if that's helpful." |
I'll submit a PR in a few days and we can figure out where to put it. |
I think there is an issue with this notion on https://esi.evetech.net/ui/#/Bookmarks/get_characters_character_id_bookmarks I think the bookmark_id should be unique in the response 200 value. I know this is a weird request but my cache compiler translates it as non-unique field, thus does not handle the modification of one BM (instead it considers all BMs are removed and new BMs are added) The same issue applies to https://esi.evetech.net/ui/#/Bookmarks/get_corporations_corporation_id_bookmarks also the folder_id of https://esi.evetech.net/ui/#/Bookmarks/get_characters_character_id_bookmarks_folders and https://esi.evetech.net/ui/#/Bookmarks/get_corporations_corporation_id_bookmarks_folders |
Isnt that something to be fixed by your compiler, whether upstream or by telling it which fields to treat as unique? |
The compiler is supposed to understand from the swagger which fields are unique. Specifying this information by hand defeats the goal of the swagger. Typically my compiler iterates over the response's fields, to find out how many of them have a description that starts with "u|Unique ". The list of fields detected as "unique" is used to know whether the cache should return a list (no or more than 1 unique), or a map(one unique). If I produce a list, I then create the cache container as an observablelist, which I put the results into when retrieving them from the ESI. If I produce a map, I transform the array of results from the ESI into a temporary map with the key being the unique field, and the values being the ESI array's items, which I then merge into the returned map. That's why I asked the Q2 in my OP : "Is the Unique keyword in the description enforced by CCP ?" |
I think the best and easiest way to solve this, would be to use dict instead of array type. I think swagger allows to return dict type, though only with a key type of string : In the case of get_characters_character_id_bookmarks, instead of having an array of bms returned, we would have a object, with additional property type is bm. The key being the id of the bm in plain text. Another example is for TheForge orders : instead of returning a plain list of unordered orders, this would return a dictionnary of orderid -> order |
The response for get_characters_character_id_bookmarks_ok is
, with TYPEDESCRIPTION being the descriptiopn of the structure with title get_characters_character_id_bookmarks_200_ok The only change required, I THINK, is to replace two lines, to get
This is the change affecting the swagger.json, of course the esi server needs to be adapted. |
Having a list of key-value couples would also open up the transmission of incremental data, since we can clearly identify the modifications between previous and present result. right now if my path returns
And next modification returns
This means, data are the same ; but the array is in a different order so I can't affirm they are the same.
Now if we have a modification between etag 1 and etag 2 , that is small enough, we would want to return not the full dict (keep in mind we may talk about 1000 values for TheForge market), but instead the incremental modification wrt the previous etag. example : first return is still same as previous. Then on etag 2 the only difference is, r2 has been removed . ATM the response 2 will be eg. with very small data.
While if data is put in dict, and sorted by key instead, it becomes possible to return
Which means the increments compared to e1 is only the deletion of r2 from the result.
This also means we need a specific header from user to return the increment instead of the full data. In the end, even though it may look like the size of data to transmit is increased, with incremental transmission |
an example of issue because of this. This is, on any language, assuming you convert the json directly into the correct type. ATM if I want the insurance price /cost of a ship, let's say the avatar ( id 11567 ). If you correct this path, that will save all devs that want to use it the need to do so. |
It's not a question (edit : it was at the beginning). It's a design bug (edit : after discussion and documentation I came to this conclusion). When an array's item have a unique attribute among the array, then this array IS a dict. It's like I ask a seller what does he sell and he tells me it's atoms. Dude I know you sell fruits, just tell me the kind of orange you sell. What's more, this is a hinder to caching the data. edit : I'm wrong, it only triggers twice for each hook on the generated cache, one from the clear() and the second from the addAll(), because observablelist handle a-whole events (one event for all removed). However it triggers 4000 times on the "correct" map : once for each bpo removed, and once again for each bpo added. |
I want to make a meta cache compiler (in java) for the ESI.
The first part is some explanation because I think context is required to understand my questions.
Code part I did
So far I have the meta cache compiler for paths that return a single element ( https://github.com/guiguilechat/EveOnline/blob/master/model/ESI-compiler/src/main/java/fr/guiguilechat/eveonline/model/esi/Compiler.java find createCache l736 )
It's very simple : when requested for the resource get_path?q=Y, if you already have the holder for this path, typically through a map of <Y, holder>, you return this holder ; else you create the self-scheduling future that will fetch the resource and store it in a holder, put it in the map, and return that holder.
Simple, nice, there are a few bugs but the idea is good I think.
It means that this method both handle the cache AND the "callback" function required to have heavy parallel requests
Now what can I do for it when the response is an array of T ?
well when the response is an item, I know that when this item changed, well THIS item changed.
When I ask for The Forge market orders, basically every 5 minute I will receive a different array of 3000 orders.
What I would like
Still some code example, sorry.
In most cases the array of items returned have a unique attribute. eg each marketorder has a"order_id" attribute that is unique, meaning I can make a map<id, order> as the response handler instead of an array of orders in a holder.
ATM the "unique" is only referenced in the description. I need to iterate over the fields, and find out if one of them has the "Unique" or "unique" keyword in its description.
If the number of fields with "unique" is not 1, I fail the cache creation (because returning a holder of marketOrder[] is completely useless wrt performances).
If it's 1, then I just make a cache of map<id, order>, and when a modification in the order list is fetched, for each order I check if the map already have this order id stored, if true I compare the new order to the stored and if they differ I replace it.
Which mean, only the orders that differ from the cached version are actually changed in the cache.
This leads to my question:
Question
I think relying on the description is a bit weird. So
The text was updated successfully, but these errors were encountered: