Unit test on a NSNotification which is sent ansynchronous by a NSTimer - objective-c

Since a few days I try to figure out how to test my API with GHUnit. Now I came to the problem to test this:
The API gets some several inputs, the CUT does something and starts an NSTimer. After the timer fired, it sends out an NSNotification with some userInfo data. It is clear how to test the userInfo data, but what I want to test is, if the notification is sent only if some certain circumstances are true and if not, it shouldn't be send at all.
How I can test it, is quite clear after reading this: http://www.hpique.com/2013/12/nsnotificationcenter-part-3/
But now the logical problem streaks in: The asynchronous behaviour of the CUT with sending out the NSNotification after the NSTimer fired. When I wait now in every test for the timer to fire, then my tests will get really slow.
How can I test the behaviour without always waiting for the NSTimer to fire? Do you have any ideas?

I don't know a way to execute synchronous tests concurrently with XCTest from within Xcode. Of course you could define several test projects and run them concurrently from the console. But I guess, this is not what you are looking for.
An asynchronous test would require that the test method returns before the assertions have been tested, but will be tested eventually. A test runner would need to know about asynchronous tests in order to handle them correctly.
With XCTest, it's not possible to have an asynchronous test. There are hints in the source code documentation which makes me believe, that this is likely not possible at all:
In the description to waitForExpectationsWithTimeout it states:
"-waitForExpectationsWithTimeout:handler: creates a point of synchronization in the flow of a test. Only one -waitForExpectationsWithTimeout:handler: can be active at any given time, but multiple discrete sequences of { expectations -> wait } can be chained together."
"waitForExpectationsWithTimeoutruns the run loop while handling events until all expectations are fulfilled or the timeout is reached. Clients should not manipulate the run loop while using this API."
So, only one waitForExpectationsWithTimeout:handler: can be active and we must not modify the underlying run loop -- this quite clearly indicates that we cannot execute tests asynchronously.
Note: you can test asynchronous methods or functions within the test method. However, in XCTest the test method itself is always synchronous - since it waits for the result to become available.

Related

Objective-C NSRunLoop & NotificationCenterDelegate not functional when spawned on Rust worker thread

I'm currently trying to use Rust C interop in order to send actional desktop notifications (using a modified version of this lib). The main goal here would be to handle these notification sending events on separate threads like so:
thread::spawn(move || unsafe {
sys::sendNotification(
NSString::from_str(&title).deref(),
NSString::from_str(&message).deref(),
NSString::from_str(&uri).deref(),
NSString::from_str(&img.unwrap_or_default()).deref(),
);
});
This would allow me to have multiple notification 'handlers' running at the same time (vs. just being able to have a single notification displayed at once), and would also allow my main process to run without being blocked. Given the nature of the program (web-scraper), I don't want scraping halted whenever a notification is being displayed.
That said, this approach is somewhat problematic because the underlying obj-c code relies on NSRunLoop to handle click events (e.g., user clicks on the action to open a web page) through the created NotificationCenterDelegate instance. Per my knowledge (feel free to fact-check me on this I'm not familiar with obj-c), NSRunLoops only operate on the main thread and this code is rendered useless if ran on a worker... The notification still sends in this scenario, but events aren't processed.
Is there a way to handle this that is more effective than running my scraping logic on a separate loop and sending notif-send events to the main thread for processing (which will probably be halted by a notification that I hadn't opened)?
Strictly speaking, there is (or can be) one NSRunLoop per thread, not only the main thread. But it's still the case that GUI stuff generally needs to run on the main thread.
I recommend that you take the approach of running scraping on a separate thread. This is generally a good idea for any combination of long-running work and GUI — it ensures that the work cannot cause the UI to hang or hiccup.

Are async routing functions and asynchronous middleware in Express blocking the execution process (in 2021)?

I know that Express allows to execute asynchronous functions in the routes and in the middlewares, but is this correct? I read the documentation and it specifies that NO ROUTES OR ASYNCHRONOUS MIDDLEWARES SHOULD BE ASSIGNED, today, currently, does Express support asynchronous functions? Does it block the execution process? o Currently asynchronous functions DO NOT BLOCK THE EXECUTION PROCESS?,
For example, if I place in an asynchronous route, and if requests are made in that route at the same time, are they resolved in parallel?, that is:
Or when assigning asynchronous routes, will these requests be resolved one after the other ?, that is:
This is what I mean by "blocking the execution process", because if one fails, are the other requests pending? or Am I misunderstanding?
I hope you can help me.
You can use async functions just fine with Express, but whether or not they block has nothing to do with whether they are async, but everything to do with what the code in the function does. If it starts an asynchronous operation and then returns, then it won't block. But, if it executes a bunch of time consuming synchronous code before it returns, that will block.
If getDBInfo() is asynchronous and returns a promise that resolves when it completes, then your examples will have the three database operations in flight at the same time. Whether or not they actually run truly in parallel depends entirely upon your database implementation, but the code you show here allows them to run in parallel if the database implements that.
The single thread of Javascript execution will run the first call to getDBInfo(), that DB request will be started and will immediately return a promise. Then, it will hit the await and it will suspend the execution of the containing function. That will allow the event loop to then start processing the second request and it will do the same. When it hits the await, it will suspend execution of the containing function and allow the event loop to process the third request will do likewise. Then, sometime later, one of the DB calls will complete (it could be any one of the three) which will resolve its promise which will unsuspend the function and it will send the response. Then, one after another the other two DB calls will finish and send their responses.

GPUImage gpus_ReturnNotPermittedKillClient crash using GPUImageFilter

I'm using GPUImageFilter in a chain, and most of the time it works OK. I've recently come across a few random crashes that match the symptoms in this github issue (albeit I'm using GPUImageFilter not live capture or video). I'm trying to find a suitable method that can ensure I've cleared the frame buffer and any other GPUImage-related activities in willResignActive.
Currently I have:
[[GPUImageContext sharedFramebufferCache] purgeAllUnassignedFramebuffers];
Is this sufficient? Should I use something else instead/in addition to?
As indicated there, seeing gpus_ReturnNotPermittedKillClient in a stack trace almost always is due to OpenGL ES operations being performed while your application is in the background or is just about to go to the background.
To deal with this, you need to guarantee that all GPUImage-related work is finished before your application heads to the background. You'll want to listen for delegate notifications that your application is heading to the background, and make sure all processing is complete before that delegate callback exits. The suggestion there by henryl is one way to ensure this. Add the following near the end of your delegate callback:
runSynchronouslyOnVideoProcessingQueue(^{
// Do some operation
});
What that will do is inject a synchronous block into the video processing pipeline (which runs on a background queue). Your delegate callback will block the main thread at that point until this block has a chance to execute, guaranteeing that all processing blocks before it have finished. That will make sure all pending operations are done (assuming you don't add new ones) before your application heads to the background.
There is a slight chance of this introducing a deadlock in your application, but I don't think any of my code in the processing pipeline calls back into the main queue. You might want to watch out for that, because if I do still have something in there that does that, this will lock your application. That internal code would need to be fixed if so.

Is there a way to update GUI or use GUI while CPU is working?

The GUI of my program freezes while the program is doing its work. I created a mass import which can send X-thousand datarows via a called webservice into a database. The code is already very big and I cannot rewrite it for multithreading purpose.
I don't know how to do it. Any suggestions? If needed I will show some code, but at the moment I don't know what to show.
Firstly, you should rewrite it to use avoid synchronously doing this on the UI thread. If you do a lot of work on the UI thread, it simply will freeze the UI thread. There are a few options here:
If your web service proxy supports asynchronous calls, and if you're using VB 11, you can use Async / Await to call the web service asynchronously from the UI thread in an asynchronous method, and control will return back to the UI thread at the same point in the asynchronous method when the call has completed. It takes a little while to get your head round asynchrony, but this is probably the best option if it's possible.
You can use the Task Parallel Library to make calls on a different thread, but then you'll need to think carefully about how that thread is going to interact with your UI thread.
You can use BackgroundWorker to run some code on another thread, but report progress and completion back on the UI thread
You could potentially call Application.DoEvents between each web service call, to let the UI handle events. This is dangerous - it can lead to re-entrant code, so locks won't behave as you expect them to, and similar hard-to-diagnose errors. This should be your last option, if all else fails.

performSelector:OnThread:waitUntilDone not executing the selector all the time

I have an app where the network activity is done in its separate thread (and the network thread continuously gets data from the server and updates the display - the display calls are made back on the main thread). When the user logs out, the main thread calls a disconnect method on the network thread as follows:
[self performSelector:#selector(disconnectWithErrorOnNetworkThread:) onThread:nThread withObject:e waitUntilDone:YES];
This selector gets called most of the time and everything works fine. However, there are times (maybe 2 out of ten times) that this call never returns (in other words the selector never gets executed) and the thread and the app just hang. Anyone know why performSelector is behaving erratically?
Please note that I need to wait until the call gets executed, that's why waitUntilDone is YES, so changing that to NO is not an option for me. Also the network thread has its run loop running (I explicitly start it when the thread is created).
Please also note that due to the continuous nature of the data transfer, I need to explicitly use NSThreads and not GCD or Operations queues.
That'll hang if:
it is attempting to perform a selector on the same thread the method was called from
the call to perform the selector is to a thread from which a synchronous call was made that triggered the perform selector
When your program is hung, have a look at the backtraces of all threads.
Note that when implementing any kind of networking concurrency, it is generally really bad to have synchronous calls from the networking code into the UI layers or onto other threads. The networking thread needs to be very responsive and, thus, just like blocking the main thread is bad, anything that can block the networking thread is a bad, too.
Note also that some APIs with callbacks don't necessarily guarantee which thread the callback will be delivered on. This can lead to intermittent lockups, as described.
Finally, don't do any active polling. Your networking thread should be fully quiescent unless some event arrives. Any kind of looped polling is bad for battery life and responsiveness.