How to create SubMonitor children for cuncurrent / parallel / asynchronous execution? - asynchronous

I can use the methods split or newChild to create a child for a SubMonitor [1]:
SubMonitor firstChild = parentMonitor.split(50);
SubMonitor secondChild = parentMonitor.split(50);
The creation of the second child automatically finishes the first child [2]:
Each SubMonitor only has one active child at a time. Each time newChild(int) or split(int) is called, the result becomes the new active child and any unused progress from the previously-active child is consumed.
This makes it unnecessary to call done() on a SubMonitor instance, since child monitors are automatically cleaned up the next time the parent is touched.
=> What is the recommended way to create child monitors if I don't want to execute one child after another but run them concurrently?
Creating the second monitor child would immediately result in a wrong total progress, since the first child is not finished yet.
Some ideas:
a) Don't use SubMonitor at all for that concurrent case but stick to the deprecated SubProgressMontior (I did not check if that would help, yet.)?
b) Somehow skip the consumption of unused progress? (The suppressFlags that can be passed to the split method do not seem to provide a value for that.)
Related questions
Eclipse plugin: How to implement progress view with log messages?
Eclipse RCP: Parallel jobs presented in one progress dialog?

Related

How to ensure ordered processing of children in ChildAdded event listener?

I need to make sure that children added to a DatabaseReference are processed in order. It is possible that the branch where the children are being added, gets multiple children added to it once. When the children are added at small intervals, everything works fine.
To tackle this, I've already implemented an index based solution. I add a field "index" in each child and ensure on Cloud Functions (the code that adds these children) that this index is incremental for all children. I then do the following to implement it:
MyDatabaseReference.OrderByChild("index").ChildAdded += HandleTheChild;
Most of the time this works, but there are still times when I get bugs similar to when I faced bugs due to wrong ordering of the children. My hypothesis is that the HandleTheChild function is triggered in order always, but it is possible that a child starts to be handled before the previous child is completely processed by the HandleTheChild function. This is creating some race conditions in their parallel execution. I want that each child be processed only after all previous children have been processed in the order they are arriving. Is my hypothesis wrong? If not, should I go forward with an implementation of the solution of the Producer-consumer problem on my Unity client?
When you first attach a listener to ChildAdded it fires for all children, in the order that you request them.
After that, the ChildAdded listener fires when a child is added to the database. In this case, the child may be inserted somewhere in the middle of the data (e.g. if its index is lower than existing indexes. The ChildAdded listener will fire and has a PreviousChildName property for this case. This contains the key/id/name of the number after which the new child was added.
My guess is that you're not using PreviousChildName, but (as Doug commented) it's hard to be certain without seeing that code.

Trigger action on completion of drag action

I'm trying to allow items from a QListWidget to be dragged to a "Trash" (A subclassed widget which accepts drops and does nothing with them).
I know that if I setDropAction(Qt.MoveAction), the items I am removing from the source will be automatically deleted. This works correctly.
My problem is that I also need to trigger an action that updates other widgets who depend upon the contents of the source.
It seems to me that the dropEvent happens before any items are actually removed from the source. I'm having a terrible time trying to figure out this problem. I've thought of two possible solutions:
Find a way to embed the references to the actual QListWidgetItems that are being dragged in the event's QMimeData. This would allow me to do the deletions by hand, before I trigger updates.
Figure out how to wait until the source has been automatically cleared, but I can't find any signals that fire when items are removed from a list automatically.
Aha!
The key I was missing was the mimeData method. This method is called when a drag is started, and in it I am passed a list of all files being dragged.
I first built the meta object to be returned, then I deleted the files being dragged from the list, and called the refresh action that I needed.
Here's an example:
def mimeData(self, items):
m = QMimeData()
m.setUrls([QUrl(i.url) for i in items])
# Clean up the list:
[self.files.takeItem(self.files.indexFromItem(i).row()) for i in items]
self._update_meta()
return m

Flex addEventListener - how to refresh the screen during called event?

I can't seem to find the answer to what I would have thought was a common problem.
What I want to do this is:
1. Show the Open File Dialog
2. Process the file selected
3. During processing the file, report progress to the User
I have a file defined, and am using the browseForOpen and AddEventListener:
public var fileInput:File = new File();
fileInput.browseForOpen("Open file",[filter]);
fileInput.addEventListener(Event.SELECT, onFileSelect);
// Step 2 - function gets called to process the file
private function onFileSelect(e:Event):void
{
// Step 3 - do some processing, and at intervals report progress to the screen
}
My issue is - any changes to the screen within the event listener do not get done until the function is complete.
Any help would be appreciated,
Thanks
Start a timer perhaps and let it check status of a variable(that denotes processing progress) as a separate running function it would not be predisposed to waiting on the parent function.
[ to be clear Im saying call a sperate function from the timer.]
But I am inclined to agree with Flextras.com in that most times I have done this the processing was milliseconds so just didnt get seen.
In Step 3, if you are doing some cpu intensive job(like huge xml parsing), then you might be seeing this NOT updating problem. As Flex is single threaded, you better make use of Green threading concept.
You can read about Green Threading here.

Is there a bug in my code for populating a QTreeView?

I'm using PyQt 4.4.
It's best shown using some pictures. All nodes should have leafs from 0 to 99. They are being incrementally loaded using canFetchMore() and fetchMore(). But for some reason unknown for me this works only for the root node. (Picture 1)
If I collapse and expand a node it loads additional 10 values. (Picture 2 & 3)
It's also strange, that it loads 10 values, as the code loads only 5 per call to fetchMore(), meaning this gets called 2 times before the code stops to load more data.
I've written a small example to demonstrate the problem, just run it with python test.py.
http://snipt.org/lLh
Does anyone know what causes this error?
I took a look at the Qt source (v4.5, though I don't expect much difference between v4.4 and v4.5) for QAbstractItemView and QTreeView, and I don't think they support incremental lazy loading of child nodes.
QAbstractItemView has no notion of trees, so it only calls fetchMore() on the top most index. It calls fetchMore() when:
Geometry is updated
The scroll bars are moved
Rows are inserted
The current item is changed as a result of an autoscrolling drag & drop operation
QTreeView additionally calls fetchMore() when:
An item is expanded (this is essentially the only time it calls fetchMore() with a non-root index)
The view's layout needs to be relaid, such as with expandAll() and collapseAll()
I think the best solution would be to subclass QTreeView to make it call fetchMore() in the appropriate places and with the appropriate indices.

Forcing Flex to update the screen?

This may be a bit of a beginners question, but I can't for the life of me figure it out.
I'm using flex to develop a GUI for a large project, specifically a status bar along the bottom. Within my StatusBar class is a ProgressBar, which other classes doing work can tell to update(change bar completion and label) as they progress. The problem I'm encountering is that flex won't update whats shown on the screen until it's too late, for example
ProgressBar initialized, 0% done
some class sets the ProgressBar to be 12% done
some class does some work
some class sets the ProgressBar to be 56% done
Whats happening is the 12% done is never displaying, it just hangs at 0% during the work, then skips right to 56% done. I've tried to understand the lifecycle of a flex component (invalidation and validation), and I think I understand it and am applying it correctly, but it's not working at all. I need to tell flex to redraw my StatusBar (or at least the ProgressBar within) after some class sets it to be 12% done, but before some class starts doing its work. How do I do this?
As mentioned in other answers, the flash player is single threaded, if you don't break up your work into discrete chunks that can be executed in separate "frames", you're going to see jumps and stutters in the ui, which is effectively what you're seeing.
If you really must see that 12% message, then it's not enough to invalidate the display list, as the display list isn't getting a chance to update until after the 56% work has completed, you must explicitly interrupt the natural event cycle with a call to validateNow() after your message has been set.
This however is not the best way to do things if performance is of concern. You might get by with judicial usage of callLater() to schedule each chunk of work in turn, as this will allow the player to potentially complete a frame cycle (and update the display list) before attempting the next step in your process.
Glenn,
That is not at all how the threading in Flex works whatsoever. Like many UIs it has a message pump on the main UI thread (they do it in frames). When you call callLater() it places the passed in function pointer at the end of the message pump queue (on the next frame) and returns immediately. The function then gets called when the message pump has finished processing all of the messages prior (like mouse clicks).
The issue is that as the property change causes UI events to be triggered, they then place their own messages on the pump which now comes after your method call that you placed there from callLater().
Flex does have multiple threads but they are there for Adobe's own reasons and therefore are not user accessible. I don't know if there is a way to guarantee that a UI update will occur at a specific point, but an option is to call callLater a number of times until the operation occurs. Start off with a small number and increase until the number of iterations produces the result you want. Example:
// Change this to a number that works... it will probably be over 1, depending on what you're doing.
private const TOTAL_CALL_COUNT:int = 5;
private var _timesCalled:int = 0;
//----------------------------------------------------------------
private function set Progress( progress:int ):void
{
progressBar.value = progress;
DoNextFunction();
}
//----------------------------------------------------------------
private function DoNextFunction():void
{
if( _timesCalled >= TOTAL_CALL_COUNT )
{
_timesCalled = 0;
Function();
}
else
{
_timesCalled++;
callLater( DoNextFunction );
}
}
Try calling invalidateDisplayList() after each changes to your progress bar. Something like :
Class StatusBar
{
public function set progress(value:uint):void
{
progressBar.value = value;
progressBar.invalidateDisplayList();
}
}
Flex has an invalidation cycle that avoid screen redrawing everytime a property changes. As an example, if a property's value changes 3 times in a single frame, it will render only with the last value set. You can force a component to be redrawn by calling invidateDisplayList() which means updateDisplayList will be immediatly executed instead of waiting the next frame.
Actionscript in Flash player, like Javascript in the browser, is pseudo-multithreaded. That is, they're single threaded, but they have multiple execution stacks. This means you can't "sleep" in a particular thread, but you can spawn a new execution stack that gets deferred until a later time. The flex way of doing this is the "callLater" function. You can also use the setTimeout/setInterval functions. Or you can use a timer object built into the flash player. Or even "ENTER_FRAME" event listener. All of these will essentially allow you to do what you need, if I'm correct about the cause of your problems.
It sounds like you have one "thread" doing most of your work, never stopping to allow other execution stacks (threads*) to run.
The problem could be what PeZ is saying, but if that doesn't help, you might want to try some deferred calls for worker classes. So your process might look like this now:
Progress initialized.
Do some work.
Update progress bar to 12. (invalidate display list)
setTimeout(doMoreWork, 100);
Update progress bar to 52.
(if your worker is a UIcomponent, you can use uicomp.callLater(...), otherwise, you need to use setTimeout/timers/enter_frame for pure AS3 classes).
Sometimes its necessary set to zero before assign another value.
progressBar.setProgress(0, progressBar.maximum);
progressBar.setProgress(newValue, progressBar.maximum);
I'm using Flash Builder 4.6 and I also have a problem for the display of my progress bar. I open a new window where I start a new multiloader class (39 Mo of content). The new window is opened in background and the main window display a progress bar until the multiloader class has finished his work. However the opening window is blocking the animation of my main window. I know it's not the multiloader class cause I saw it running correctly.
But I will try to find some new ways of doing it.
The main purpose of my post is the complexity adobe has build around flash.
When you seek ressources for your own application or answers for your questions, it's a real pain to find the good ressource. There is a total mix up (at adobe side and at user side) between AS3, Flex, Flash CS, Flash Builder, AiR, ... If you try to develop in AS3, you will find that some examples won't work for you because it is not implemented in your SDK. You have more and more forums giving you the "best practice" or ironic answers based on experiences on different developping platform.
By example, just here above, I see progressBar.value = value; With my experience, I can say that in Flash Builder 4.6, this property is read-only. But It might be a custom class made by the user but who can tell.

Resources