I have used playback. wait(3000) in my Coded Ui Script, to wait until my website it loaded. Sometimes the script fails, if the website takes more time to load. Is there any other way to wait until page is loaded ?
PlayBack.Wait() is simply a sleep statement, which would wait unconditionally for given number of time. For UI Sync you should consider using waitfor statements. Something like below,
// Set the playback to wait for all threads to finish
Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.AllThreads;
// Wait till your control is read (Loaded)
browserWindow.WaitForControlReady();
// Reset the playback to wait only for the UI thread to finish
Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.UIThreadOnly;
Take a look at other wait statements as well to sync your app better.
Related
How can I pause execution for a certain amount of time in Godot?
I can't really find a clear answer.
The equivalent of Thread.Sleep(1000); for Godot is OS.DelayMsec(1000). The documentation says:
Delays execution of the current thread by msec milliseconds. msec must be greater than or equal to 0. Otherwise, delay_msec will do nothing and will print an error message.
Note: delay_msec is a blocking way to delay code execution. To delay code execution in a non-blocking way, see SceneTree.create_timer. Yielding with SceneTree.create_timer will delay the execution of code placed below the yield without affecting the rest of the project (or editor, for EditorPlugins and EditorScripts).
Note: When delay_msec is called on the main thread, it will freeze the project and will prevent it from redrawing and registering input until the delay has passed. When using delay_msec as part of an EditorPlugin or EditorScript, it will freeze the editor but won't freeze the project if it is currently running (since the project is an independent child process).
One-liner:
yield(get_tree().create_timer(1), "timeout")
This will delay the execution of the following line for 1 second.
Usually I make this to a sleep() function for convenience:
func sleep(sec):
yield(get_tree().create_timer(sec), "timeout")
Call it with sleep(1) to delay 1 second.
I have read that fs.readFile is an asynchronous operation and the reading takes place in a separate thread other than the main thread and hence the main thread execution is not blocked. So I wanted to try out something like below
// reads take almost 12-15ms
fs.readFile('./file.txt', (err, data) => {
console.log('FIRST READ', Date.now() - start)
const now = Date.now()
fs.readFile('./file.txt', (err, data) => {
// logs how much time it took from the beginning
console.log('NESTED READ CALLBACK', Date.now() - start)
})
// blocks untill 20ms more, untill the above read operation is done
// so that the above read operation is done and another callback is queued in the poll phase
while (Date.now() - now < 20) {}
console.log('AFTER BLOCKING', Date.now() - start)
})
I am making another fs.readFile call inside the callback of parent fs.readFile call. What I am expecting is that the log NESTED READ CALLBACK must arrive immediately after AFTER BLOCKING since, the reading must be completed asynchronously in a separate thread
Turns out the log NESTED READ CALLBACK comes 15ms after the AFTER BLOCKING call, indicating that while I was blocking in the while loop, the async read operation somehow never took place. By the way the while loop is there to model some task that takes 20ms to complete
What exactly is happening here? Or am I missing some information here? Btw I am using windows
During your while() loop, no events in Javascript will be processed and none of your Javascript code will run (because you are blocking the event loop from processing by just looping).
The disk operations can make some progress (as they do some work in a system thread), but their results will not be processed until your while loop is done. But, because the fs.readFile() actually consists of three or more operations, fs.open(), fs.read() and fs.close(), it probably won't get very far while the event loop is blocked because it needs events to be processed to advance through the different stages of its work.
Turns out the log NESTED READ CALLBACK comes 15ms after the AFTER BLOCKING call, indicating that while I was blocking in the while loop, the async read operation somehow never took place. By the way the while loop is there to model some task that takes 20ms to complete
What exactly is happening here?
fs.readFile() is not a single monolithic operation. Instead, it consists of fs.open(), fs.read() and fs.close() and the sequencing of those is run in user-land Javascript in the main thread. So, while you are blocking the main thread with your while() loop, the fs.readFile() can't make a lot of progress. Probably what happens is you initiate the second fs.readFile() operation and that kicks off the fs.open() operation. That gets sent off to an OS thread in the libuv thread pool. Then, you block the event loop with your while() loop. While that loop is blocking the event loop, the fs.open() completes and (internal to the libuv event loop) an event is placed into the event queue to call the completion callback for the fs.open() call. But, the event loop is blocked by your loop so that callback can't get called immediately. Thus, any further progress on completing the fs.readFile() operation is blocked until the event loop frees up and can process waiting events again.
When your while() loop finishes, then control returns to the event loop and the completion callback for the fs.open() call gets called while will then initiate the reading of the actual data from the file.
FYI, you can actually inspect the code yourself for fs.readFile() right here in the Github repository. If you follow its flow, you will see that, from its own Javascript, it first calls binding.open() which is a native code operation and then, when that completes and Javascript is able to process the completion event through the event queue, it will then run the fucntion readFileAfterOpen(...) which will call bind.fstat() (another native code operation) and then, when that completes and Javascript is able to process the completion event
through the event queue, it will then call `readFileAfterStat(...) which will allocate a buffer and initiate the read operation.
Here, the code gets momentarily harder to follow as flow skips over to a read_file_context object here where eventually it calls read() and again when that completes and Javascript is able to process the completion event via the event loop, it can advance the process some more, eventually reading all the bytes from the file into a buffer, closing the file and then calling the final callback.
The point of all this detail is to illustrate how fs.readFile() is written itself in Javascript and consists of multiple steps (some of which call code which will use some native code in a different thread), but can only advance from one step to the next when the event loop is able to process new events. So, if you are blocking the event loop with a while loop, then fs.readFile() will get stuck between steps and not be able to advance. It will only be able to advance and eventually finish when the event loop is able to process events.
An analogy
Here's a simple analogy. You ask your brother to do you a favor and go to three stores for you to pick up things for dinner. You give him the list and destination for the first store and then you ask him to call you on your cell phone after he's done at the first store and you'll give him the second destination and the list for that store. He heads off to the first store.
Meanwhile you call your girlfriend on your cell phone and start having a long conversation with her. Your brother finishes at the first store and calls you, but you're ignoring his call because you're still talking to your girlfriend. Your brother gets stuck on his mission of running errands because he needs to talk to you to find out what the next step is.
In this analogy, the cell phone is kind of like the event loop's ability to process the next event. If you are blocking his ability to call you on the phone, then he can't advance to his next step (the event loop is blocked). His visits to the three stores are like the individual steps involved in carrying out the fs.readfile() operation.
I know how to wait in Linux kernel queues using wait_event and how to wake them up.
Now I need to figure out how to wait in multiple queues at once. I need to multiplex multiple event sources, basically in a way similar to poll or select, but since the sources of events don't have the form of a pollable file descriptor, I wasn't able to find inspiration in the implementation of these syscalls.
My initial idea was to take the code from the wait_event macro, use DEFINE_WAIT multiple times as well as prepare_to_wait.
However, given how prepare_to_wait is implemented, I'm afraid the internal linked list of the queue would become corrupted if the same "waiter" is added multiple times (which could maybe happen if one queue causes wakeup, but the wait condition isn't met and waiting is being restarted).
One of possible scenarios for wait in several waitqueues:
int ret = 0; // Result of waiting; in form 0/-err.
// Define wait objects, one object per waitqueue.
DEFINE_WAIT_FUNC(wait1, default_wake_function);
DEFINE_WAIT_FUNC(wait2, default_wake_function);
// Add ourselves to all waitqueues.
add_wait_queue(wq1, &wait1);
add_wait_queue(wq2, &wait2);
// Waiting cycle
while(1) {
// Change task state for waiting.
// NOTE: this should come **before** condition checking for avoid races.
set_current_state(TASK_INTERRUPTIBLE);
// Check condition(s) which we are waiting
if(cond) break;
// Need to wait
schedule();
// Check if waiting has been interrupted by signal
if (signal_pending(current)) {
ret = -ERESTARTSYS;
break;
}
}
// Remove ourselves from all waitqueues.
remove_wait_queue(wq1, &wait1);
remove_wait_queue(wq2, &wait2);
// Restore task state
__set_current_state(TASK_RUNNING);
// 'ret' contains result of waiting.
Note, that this scenario is slightly different from one of wait_event:
wait_event uses autoremove_wake_function for wait object (created with DEFINE_WAIT). This function, called from wake_up(), removes wait object from the queue. So it is needed to re-add wait object into the queue each iteration.
But in case of multiple waitqueues it is impossible to know, which waitqueue has fired. So following this strategy would require to re-add every wait object every iteration, which is inefficient.
Instead, our scenario uses default_wake_function for wait object, so the object is not removed from the waitqueue on wake_up() call, and it is sufficient to add wait object to the queue only once, before the loop.
I have a Meteor server method that executes a function that I want to run in the background. I want the server method to continue while the function runs in a different process.
the method:
myMethod: function(arg) {
_event.emit("myEvent",args);
...do some other stuff
}
I'd like the server to do the other stuff and return to the client, and to do the stuff in _event.emit in the background no results have to be sent back to the client.
What it currently does is run the stuff in _event.emit and than the other stuff and then return to the client.
I tried to solve it by doing a call on server side with an empty callback function, but that didn't do the trick
myMethod: function (arg) {
return Meteor.call("secondMethod", _.toArray(arg), function() {})
}
secondMethod: function (arg) {
_event.emit("myEvent",args);
}
hope someone knows a solution for this.
thanks
The javascript in nodejs is single threaded. It works off an event queue where an event is popped off the queue, some callback is called to serve that event and the code behind that callback runs to completion, then the next event is pulled off the event queue and the process is repeated.
As such, there is no real "background processing". If your JS thread is executing, then nothing else can run at that time until that JS thread finishes and allows the next event in the event queue to be processed.
To truly run something else in parallel where both your task and other nodejs code can literally run at the same time, you would have to create a new process and let the new process carry out your task. This new process could be any type of process (some pre-built program running a task or another custom nodejs process).
"Running in the background" can sometimes be simulated by time slicing your "background" process work such that it does small amounts of work on timer ticks and the pauses between timer ticks allow other nodejs JS events to be processed and their code to run. But, to do this type of simulated "background", you have to write your task to execute in small chunks. It's a different (and often more cumbersome) way of writing code.
On the server you can just use Meteor.setTimeout() to run a function asynchronously. Just use an interval of zero if you want to return control immediately. Your main function will continue to run and as soon as there's nothing left in the event queue the scheduled task will run (or it will wait the amount of time you specify if non-zero).
I have created a Single Dialog application which basically does a series of complex calculation. The application was first created as a Win32 console application and later I decided to add a progressbar and then I converted the console application to a Single Dialog based application. The dialog has a progressbar on it. in OnInitDialog() function of the dialog, I start the calculations. The calculations are running on a worker thread. This thread is created by calling _beginthreadex function. The progressbar is updated by the thread by posting messages to the Dialog by using PostMessage. After the thread has completed execution, I call CDialog::OnOK() function to close the dialog. The issue is that, even after the dialog is closed, the application is not end immediately. It takes nearly 2 seconds to close the application even though the dialog is closed.
Any help to solve this issue is highly appreciated.
Thanks.
It's because your worker thread is still running. The application will not terminate until all threads are finished running. Since your UI thread closes before the worker thread, the window may be hidden, but the process does not terminate until the worker thread has completed its work.
The worker thread might be still running. To make sure that the thread is stopped use events to signal . you can signal an event to kill the thread when the user presses close button in the dialog.
You can check whether the event is signaled inside your complex calculation (may be a loop) and break from it. Thus stopping the thread without any issues.
while(true)
{
//Some complex task
DWORD dwWaitResult;
dwWaitResult = WaitForSingleObject(hwndShutdownEvent,0);
if (WAIT_OBJECT_0 == dwWaitResult)
{
break;
}
}