-
Notifications
You must be signed in to change notification settings - Fork 0
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
Session History/Multiple Popup #37
Comments
As we work through the design, I'd like us to keep in mind that we can leverage browser caching of remote HTTP requests/responses so that not all query results need to be kept in memory for each word in the history. |
Per @irina060981 we need to define the following requirements for session history:
|
I'd like to offer this as a first draft of a revised data model for discussion. The model objects shown in a contained-by relationship (with the filled diamond) cannot exist outside of the context of their container. Those shown as a aggregated-by relationship (with the un-filled diamond) can exist as data objects separate from their container but are still directly part of model object (even if only by reference). And those that are shown with a directed relationship (the dotted line arrow) can exist as data objects separate from the related object, and may be accessed through the data model object but are not contained by or belonging to it. So, for example, a Anytime a user looks up a word, either by clicking on it on the page or from an alpheios display, or in the lookup box, a The I'm showing a general concept of a A Both A Everything shown in the containment hierarchy with a Full Definitions, Usage Examples, Word Translations, InflectionViewSets ( and other resources such as Linked Resources) are distinct from the context of a specific @kirlat and @irina060981 please let me know your thoughts on this. |
What if we try to break complexity down into smaller, more controllable pieces? I think we can identify the following types of resources relatively independent from each other:
All those data items could be stored and retrieved independently. Each piece of resource data is relatively simple by itself. A data item, or several data items, can be obtained with GraphQL queries from a service that is responsible for obtaining and keeping this data for a certain period of time. Let's call it the Resource Service. It could be a GraphQL server or something else, I want to keep implementation details out of scope of this discussion. There could be several Resource Services each responsible for single type of resources. We could also have a single service that will be able to retrieve all types of resources. In the latter case a GraphQL query will specify what types of resource have to be obtained. The latter case, however, may have a hard-to-solve problem with different retrieval times for different types of data (i.e. the whole request may wait for the slowest resource data to arrive and that will make user to wait for results in limbo for too long). Let's call instances of individual resource type items the Resource Objects. There are also grouping entities. Let's call them the Grouping Objects:
And we also have two lists (the Lists):
So we have three groups of objects (the Resource Objects, the Grouping Object, and the Lists) with a slightly different role each. The purpose of Resource Objects is to keep data. They would most likely have almost no business logic. Nor would they have any knowledge of each other. The Grouping Objects holds references to Resource Objects or other Grouping Objects. They keep almost no data of their own other than lists of resources or other grouping objects that comprises them. They, however, may have business logic. For example, the Homonym Object may have a method to return all the Inflections kept within the Lexemes it holds. The interesting thing about the Grouping Objects is that they can have not all the Resource Objects all the time. Yet the Grouping Objects can be useful (and be used) even in such "incomplete" state. For example, a homonym may have lexemes with lemmas only, and those lemmas may have only short definitions. Yet a Homonym object in a state like that can still be shown in a popup. It may retrieve full definitions later. It may obtain translations later too, if user has enabled a lemma translation options in the settings. Because data inside such objects are not in one constant state but may change over time, we can call them the Live Objects. When the user selects the word on a page, a Lexical Query decides what types of resources are needed initially. This may depend on the context, options, user preferences, and other factors. Upon a word selection a Lexical Query creates a Grouping Object (a Word most likely) and issues GraphQL requests to the Resource Services that corresponds types of data to be obtained (Lemmas and Short Definitions, for example). The Resource Service checks if data is available locally and if not, retrieves it remotely. It then returns data back to the Lexical Query. Once data is arrived to the Lexical Query, the Grouping Object (the Word) is populated and put into use (i.e. displayed to the user). The Word object will not have the full data set at that stage. It will not have Full Definitions data, for example. This data can be obtained in two ways:
So the Live Objects would change their state depending on user requests for data (like when user requests full definitions). The Live Objects may also react to other changes. If user chose to disable lemma translations in options, the Lexeme may drop lemma translations. If user later decides to enable translations again, the Live Object may request it from the Translations Service in order to re-populate itself. If the Translation Service has kept this data in cache all this time, it will return it immediately. Otherwise, data will be deferred until received from the remote serer. So that's the concept I suggest to explore and discuss. I think it can be beneficial because it simplifies things by reducing inter-dependencies. I also think that it offers an expandable model because we can add new types of resources easily, with minimal change to the model. All pieces of the model are pretty well isolated from each other which allows to update and test them easily. @balmas, @irina060981, what do you think about a model like that? |
I think this is a very helpful way to model things. Having trouble finding a flaw in it. I wonder if there is a way we could try it out in a small way before refactoring everything to see if it works? |
I think the safest way to verify feasibility is to start introducing the new workflow in parallel with the existing one. We can create a new version of a lexical request object (or add new methods to the existing one) and, initially, run the request through both old and new objects in parallel. With this we can verify that the data retrieved via the new workflow is the same as obtained through the old one. Then we can start switching UI components one by one to get data from the new workflow. After this change is complete, we can start to remove pieces of the old workflow. What do you think? |
I was wondering if we could start even smaller than that, to test out the concept of the model on a very discrete piece of functionality. I'm not sure if it's feasible. |
The other change that the history would require is a creation of a history object that will keep a history of all lexical requests. Right now, if the homonym is retrieved by the lexical query, it is saved to the prop of the app controller, inside the In order to satisfy requirements from this issue we could create a Once the lexical data for a word is retrieved, a new Thus, via the Items inside the What do you think about the changes like that? |
Above I proposed
What do you see as the difference between a |
I am not completely sure but I was thinking about @irina060981 words of data model objects being reused in other applications. I'm also thinking about the separation of concerns. Whatever object representing the lexical query results is saved in a history list it should be able to return the query results in different forms. It must have various methods for that. In order to do so, it probably has to keep some GrahpQL response data in the "raw" form inside. If we decide to introduce the But if we don't want the That's my reasoning behind having a separate |
To be honest, I'm not sure. Overall I agree that we need a place to store and manage the session history and a place to store and manage accumulated word data. Whether we need both a Word model and a Word data object remains to be seen I think. I suggest we proceed and see how it goes. |
This issue is to discuss the design for the following requirements:
(moved from #33)
The text was updated successfully, but these errors were encountered: