Should ErrorCollector (which is part of JSR-303 functionality) in GWT 2.4 be redesigned? - gwt

I know this question is not about particular problem I have. It's rather question to GWT SDK team. As far as I remember StackOverflow is now their official communication channel with engineering community :)
Problem:
For aliased editors such as ValueBoxEditorDecorator you'll receive duplicate errors in your HasEditorErrors.showErrors() - one for ValueBoxEditorDecorator itself and another one for nested ValueBoxEditor. Current implementation of ValueBoxEditorDecorator iterates through list of errors and rejects ones that don't belong to nested editor. It looks like a hacky workaround to me :)
Question:
I think duplicates should be discarded somewhere earlier, for example in SimpleViolation.pushViolations or DelegateMap.of or ErrorCollector.endVisit.
Initially I thought why not just keep one delegate per unique EditorContext.getAbsolutePath and drop the rest. Then I realized that perhaps there is a use-case when ValueBoxEditorDecorator and its inner ValueBoxEditor would get different errors although I can't come up with the scenario how it can happen due to my short-time knowledge of gwt's sources.
So here is what I think. Why don't we use map in ErrorCollector.errorStack instead of List where the key will be combination of EditorError.getAbsolutePath() and EditorError.getUserData() ? It would solve two issues IMO:
We won't need to filter out dupkicate errors in our editors.
ErrorCollector.visit() won't assume that editors like this one are traversed in hierarchical order. I don't see anywhere in documentation that visitors would always work that way.
What do you think ?

Related

Does the Javascript Firestore client cache document references?

Just in case I'm trying to solve the XY problem here, here's some context (domain is a role-playing game companion app). I have a document (campaign), which has a collection (characters), and I'm working with angular.io / angularfire.
The core problem here is that if I query the collection of characters on a campaign, I get back Observable<Character[]>. I can use that in an *ngFor let character of characters | async just fine, but this ends up being a little messy downstream - I really want to do something like have the attributes block as a standalone component (<character-attributes [character]="character">) and so on.
This ends up meaning down in the actual display components, I have a mixture of items that change via ngOnChanges (stuff that comes from the character) and items that are observable (things injected by global services like the User playing a particular Character).
I have a couple options for making this cleaner (the zeroth being: just ignore it).
One: I could flatten all the possible dependencies into scalars instead of observables (probably by treating things like the attributes as a real only-view component and injecting more data as a direct input - <character-attributes [character]="" [player]="" [gm]=""> etc. Displayable changes kind of take care of themselves.
Two: I could find some magical way to convert an Observable<Character[]> into an Observable<Observable<Character>[]> which is kind of what I want, and then pass the Character observable down into the various character display blocks (there's a few different display options, depending on whether you're a player (so you want much more details of your character, and small info on everything else) or a GM (so you want intermediate details on everything that can expand into details anywhere).
Three: Instead of passing a whole Character into my component, I could pass character.id and have child components construct an observable for it in ngOnInit. (or maybe switchMap in ngOnChanges, it's unclear if the angular runtime will reuse actual components for different items by changing out the arguments, but that's a different stack overflow question). In this case, I'd be doing multiple reads of the same document - once in a query to get all characters, and once in each view component that is given the characterId and needs to fetch an observable of the character in question.
So the question is: if I do firestore.collection('/foo/1/bars').valueChanges() and later do firestore.doc('/foo/1/bars/1').valueChanges() in three different locations in the code, does that call four firestore reads (for billing purposes), one read, or two (one for the query and one for the doc)?
I dug into the firebase javascript sdk, and it looks like it's possible that the eventmanager handles multiple queries for the same item by just maintaining an array of listeners, but I quite frankly am not confident in my code archaeology here yet.
There's probably an option four here somewhere too. I might be over-engineering this, but this particular toy project is primarily so I can wrestle with best-practices in firestore, so I want to figure out what the right approach is.
I looked at the code linked from the SDK and it might be the library is smart enough to optimize multiple observers of the same document to just read the document once. However this is an implementation detail that is dangerous to rely on, as it could change without notice because it's not part of the public API.
On one hand, if you have the danger above in mind and are still willing to investigate, then you may create some test program to discover how things work as of today, either by checking the reads usage from the Console UI or by temporarily modifying the SDK source adding some logging to help you understand what's happening under the hood.
On the other hand, I believe part of the question arises from a application state management perspective. In fact, both listening to the collection or listening to each individual document will notify the same changes to the app, IMO what differs here is how data will flow across the components and how these changes will be managed. In that aspect I would chose whatever approach feels better codewise.
Hope this helps somewhat.

Multiple Models

I like knockoutjs, the sooner we get rid of coding directly toward the DOM the better. I'm having trouble understanding how I would do something which I'm going to explain in terms of a question/answer site. (This is probably a general MVC/MVVM question)
In my data model I have a question[id, description] and answer[id, question_id, text]. The browser requests a list of questions which is bound to a tbody, one column will display the question description, while the other should be bound to an answer textbox.
One obvious way of doing this is to have a QuestionAnswer[question_id, answer_id, question_descrition, answer_text] model. Ideally I'd like to keep them separate to minimize transformation when sending/receiving/storing, if there isn't some way of keeping them separate then I have the following question:
Where is the ideal place to create the QuestionAnswer model ? My bet is that by convention its created on the server.
If there is such an example somewhere please point me to it, otherwise I think it would make a good example.
Please help me wrap my head around this, Thanks!
What you could do is to create the combined model on the server, serialize it to json and then use the mapping plugin to add the serialized list to the view model.
I'm doing that here only it isn't a combined model, but shouldn't make any difference. Especially since it seems like your relation is one-to-one.
If you need to create an "object" in your view model, you can use the mapping definition to do so, like I do here.
I use C# to build my model on the server, but I guess you can use whatever you are comfortable with.
The cool thing with the mapping plugin is that it adds the data to the view model so that you can focus on behaviour.
Ok,
I'v gathered my thoughts on what my question is actually asking.
To do data binding on the client side you obviously need your data model there as well. I was conflicted on what I needed to send over and at what time.
To continue with the Question/Answer site idea: Sending down a list of answers each of which have a question in them is what should be done. That way you can bind to the answer list and simply bind the question description of each answer to the first table column.
If later I want to make a question editor I would potentially send a complete different data structure down and not reuse the Answer has a Question structure previously used.
I thought there might be a way of sending down a more complex data structure that references itself. Which apparently is possible in JSon with some extra libraries.

Lazy and Deferred TreeViewer questions

I have actually two questions but they are kind of related so here they go as one...
How to ensure garbage collection of tree nodes that are not currently displayed using TreeViewer(SWT.VIRTUAL) and ILazeTreeContentProvider?
If a node has 5000 children, once they are displayed by the viewer they are never let go,
hence Out of Memory Error if your tree has great number of nodes and leafs and not big enough heap size.
Is there some kind of a best practice how to avoid memory leakages, caused by never closed view holding a treeviewer with great amounts of data (hundreds of thousands objects or even millions)?
Perhaps maybe there is some callback interface which allow greater flexibility with viewer/content provider elements?
Is it possible to combine deffered (DeferredTreeContentManager) AND lazy (ILazyTreeContentProvider) loading for a single TreeViewer(SWT.VIRTUAL)?
As much as I understand by looking at examples and APIs, it is only possible to use either one at a given time but not both in conjunction, e.g. ,
fetch ONLY the visible children for a given node AND fetch them in a separate thread using Job API. What bothers me is that Deferred approach
loads ALL children. Although in a different thread, you It still load all elements
even though only a minimal subset are displayed at once.
I can provide code examples to my questions if required...
I am currently struggling with those myself so If I manage to come up with something in the meantime I will gladly share it here.
Thanks!
Regards,
Svilen
I find the Eclipse framework sometimes schizophrenic. I suspect that the DeferredTreeContentManager as it relates to the ILazyTreeContentProvider is one of these cases.
In another example, at EclipseCon this past year they recommended that you use adapter factories (IAdapterFactory) to adapt your models to the binding context needed at the time. For example, if you want your model to show up in a tree, do it this way.
treeViewer = new TreeViewer(parent, SWT.BORDER);
IAdapterFactory adapterFactory = new AdapterFactory();
Platform.getAdapterManager().registerAdapters(adapterFactory, SomePojo.class);
treeViewer.setLabelProvider(new WorkbenchLabelProvider());
treeViewer.setContentProvider(new BaseWorkbenchContentProvider());
Register your adapter and the BaseWorkbenchContentProvider will find the adaption in the factory. Wonderful. Sounds like a plan.
"Oh by-the-way, when you have large datasets, please do it this way", they say:
TableViewertableViewer = new TableViewer(parent, SWT.VIRTUAL);
// skipping the noise
tableViewer.setItemCount(100000);
tableViewer.setContentProvider(new LazyContentProvider());
tableViewer.setLabelProvider(new TableLabelProvider());
tableViewer.setUseHashlookup(true);
tableViewer.setInput(null);
It turns out that first and second examples are not only incompatible, but they're mutually exclusive. These two approaches where probably implemented by different teams that didn't have a common plan or maybe the API is in the middle of a transition to a common framework. Nevertheless you're on your own.

Is there a better way to use sorting and filtering with ILazyTreeContentProvider

Apparently if using ILazyTree(TreePath)ContentProvider sorting and filtering is not supported by TreeViewers. So setting ViewerFilters or Sorters/Comparators to your TreeView won't do any good. Perhaps this is related to not knowing all elements, including those not visible at the moment.
In support to this statement here is javadoc excerpt from org.eclipse.jface.viewers.TreeViewer class:
If the content provider is an
ILazyTreeContentProvider or an
ILazyTreePathContentProvider, the underlying Tree must be
created using the {#link SWT#VIRTUAL} style bit, the tree viewer will not
support sorting or filtering, and hash lookup must be enabled by calling
{#link #setUseHashlookup(boolean)}.
The only solution I see at the moment is to get the children for each node already ordered. If you need dynamic sorting, i.e., being able to switch sorting order in desc or asc order during run time, then you need to come up with your own solution for this, monitoring a boolean flag of sorts when filling and updating children for example.
Are you aware possibly of better solutions, perhaps more jface API involving?
Indeed, sorting is not possible for a VIRTUAL-TreeViewer whether you use a IStructuredContentProvider or a lazy one, as noted in this thread:
You will have to do the sorting yourself (in your model).
The underlying assumption is that the elements might not even be in memory.
Things may change in e4 (from this message in June 2009):
IMHO the JFace Virtual Table and Tree implementation is not as good as the none virtual one - well I stay away from it and use it in none of my projects.
[...] its senseless to have virtual tables because from an UI-Design point of view it is senseless to show an user 10.000s of elements and even more important because the model
stays resident in your memory showing big tables with JFace might eat up
all your heapspace
(We hope to come up with a redesigned set of Viewers in E4 who fix such problems).
See this project and bug 260451.
(more genral bugs: 167436 and 262160)
Right now:
we are creating a strong reference in the viewer after the table requested it.
IMHO its much better to give the user:
- paging
- intelligent filtering possibilities
instead of showing million of results and then e.g. in case of CDO (Connected Data Objects) the filtering happens on the server using their new query-API.

How to address semantic issues with tag-based web sites

Tag-based web sites often suffer from the delicacy of language such as synonyms, homonyms, etc. For programmers looking for information, say on Stack Overflow, concrete examples are:
Subversion or SVN (or svn, with case-sensitive tags)
.NET or Mono
[Will add more]
The problem is that we do want to preserve our delicacy of language and make the machine deal with it as good as possible.
A site like del.icio.us sees its tag base grow a lot, thus probably hindering usage or search. Searching for SVN-related entries will probably list a majority of entries with both subversion and svn tags, but I can think of three issues:
A search is incomplete as many entries may not have both tags (which are 'synonyms').
A search is less useful as Q/A often lead to more Qs! Notably for newbies on a given topic.
Tagging a question (note: or an answer separately, sounds useful) becomes philosophical: 'Did I Tag the Right Way?'
One way to address these issues is to create semantic links between tags, so that subversion and SVN are automatically bound by the system, not by poor users.
Is it an approach that sounds good/feasible/attractive/useful? How to implement it efficiently?
Recognizing synonyms and semantic connections is something that humans are good at; a solution to organizing an open-ended taxonomy like what SO is featuring would probably be well served by finding a way to leave the matching to humans.
One general approach: someone (or some team) reviews new tags on a daily basis. New synonyms are added to synonym groups. Searches hit synonym groups (or, more nuanced, hit either literal matches or synonym group matches according to user preference).
This requires support for synonym groups on the back end (work for the dev team). It requires a tag wrangler or ten (work for the principals or for trusted users). It doesn't require constant scaling, though—the rate at which the total tag pool grows will likely (after the initial Here Comes Everybody bump of the open beta) will in all likelihood decrease over time, as any organic lexicon's growth-rate does.
Synonymy strikes me as the go-to issue. Hierarchical mapping is an ambitious and more complicated issue; it may be worth it or it may not be, but given the relative complexity of defining the hierarchy it'd probably be better left as a Phase 2 to any potential synonym project's Phase 1.
The way the software on blogspot.com is set up, is that there is an ajax-autocomplete-thingie on the box where you write the name of the tags. This searches all your previous posts for tags that start with the same letters. At least that way you catch different casings and spellings (but not synonyms).
How would the system know which tags to semantically link? Would it keep an ever-growing map of tags? I can't see that working. What if someone typed sbversion instead? How would that get linked?
I think that asking the user when they submit tags could work. For example, "You've entered the following tags: sbversion, pascal and bindings. Did you mean, "Subversion", "Pascal" and "Bindings"?
Obviously the system would have to have a fairly smart matching system for that to work. Doing it this way would be extra input for the user (which'd probably annoy them) but the human input would, if done correctly, make for less duplicate tags.
In fact, having said all that, the system could use the results of the user's input as a basis for automatic tag matching. From the previous example, someone creates a tag of "sbversion" and when prompted changes it to "Subversion" - the system could learn that and do it automatically next time.
Part of the issue you're looking at is that English is rife with synonyms - are the following different: build-management, subversion, cvs, source-control?
Maybe, maybe not. Having a system, like the one [now] in use on SO that brings up the tag you probably meant is extremely helpful. But it doesn't stop people from bulling-through the tagging process.
Maybe you could refuse to accept "new" tags without a user-interaction? Before you let 'sbversion' go in, force a spelling check?
This is definitely an interesting problem. I asked an open question similar to this on my blog last year. A couple of the responses were quite insightful.
I completely agree. The mass of tags that have currently. I don't participate in other tagged based sites. However having a hierarchy of tags would be very helpful, instead of ruby rails ruby-on-rails rubyonrails etc...
Tags are basically our admission that search algorithms aren't up to snuff. If we can get a computer to be smart enough to identify that things tagged "Subversion" have similar content to things tagged "svn", presumably we can parse the contents, so why not skip tags altogether, and match a search term directly to the content (i.e., autotagging, which is basically mapping keywords to results)?!
The problem is to make the search engine use the fact that 'subversion' and 'svn' are very similar to the point that they mean the same 'thing'.
It might be attractive to compute a simple similarity between tags based on frequency: 'subversion' and 'svn' appear very often together, so requesting 'svn' would return SVN-related questions, but also the rare questions only tagged 'subversion' (and vice versa). However, 'java' and 'c#' also appear often together, but for very different reasons (they are not synonyms). So similarity based on frequency is out.
An answer to this problem might be a mix of mechanisms, as the ones suggested in this Q/A thread:
Filtering out typos by suggesting tags when the user inputs them.
Maintaining a user-generated map of synonyms. This map may not be that big if it just targets synonyms.
Allowing multi-tag search, such that the user can put 'subversion svn' or 'subversion && svn' (well, from programmers to programmers) in the search box and get both. This would be quite practical as many users may actually try such approach when they do not know which term is the most meaningful.
#Nick: Agreed. The question is not meant to argue against tags. Tags have great potential, but users will face a growing issue if one cannot search 'across' tags.
#Steve: Maintaining an ever-growing map of tags is definitely not practical. As SO is accumulating an ever-growing bag of tags, how could we shade some light on this bag to make search of Q/A tags even more useful, in a convenient way?
#Espo: 'Ajax-powered' tag suggestions based on existing tags is apparently available on SO when creating a question. This is by the way very helpful to choose tags and appropriate spelling (avoiding the 'subversion' vs. 'sbversion' issue from Steve).