What is the Cocoa-way of observing progress of a background task? - multithreading

Imagine the following situation: you have a background task (the term "task" here means a random computational unit, not an NSTask!), that is implemented using any of the modern technology such as Grand Central Dispatch or Operation Queues. Some controller object on main thread wants to monitor the progress of this background task and report it to a user.
Task progress can have following characteristics:
Be indeterminate or determinate
Because controller object must know when to switch NSProgressIndicator to the appropriate style. We can use a convention that progress is treated as indeterminate until the actual progress value raises from zero.
Progress value itself
A simple float value
Localized description of a current phase
NSString, because communication with user is good
What design suits these requirements at best while being the most Cocoa-ish?
There can be variants.
Delegation
Before firing up the task set your controller object as delegate.
#protocol MyBackgroundTaskDelegate
#required
- (void) progress: (float) value; // 0.0…1.0
#optional
- (void) workingOn: (NSString*) msg; // #"Doing this, doing that…"
#end
Actually, i successfully used this template many times, but it feels a little too verbose.
Block callback
Very similar to delegation, but keeps code in one place.
// Starting our background task...
[MyTask startComputationWithProgressHandler: ^(float progress, NSString* msg)
{
// Switching to the main thread because all UI stuff should go there...
dispatch_async(dispatch_get_main_queue(), ^()
{
self.progressIndicator.progress = progress;
self.informationalMessage = msg;
});
}];
KVO or polling of a progress properties
In this case background task object must have two properties similar to these:
#property(readonly, atomic) float progress;
#property(readonly, atomic) NSString* message;
And a client (our controller object) should set itself as an observer of these properties. The major flaw i see in this solution is that KVO-notifications always arrive on the same thread that caused the change. While you can force your observer (callback) method to run on a particular GCD queue it may not be always appropriate.
NSNotificationCenter
Background task sends notifications and client listens to them.
Is there any other patterns applicable to this situation? What solution can be treated as a most modern and Cocoa-ish?

When it comes to What is the Cocoa-way of observing progress of a background task? I would say delegation and NSNotificationCenter because blocks and KVO were introduced later, and hence didn't originally exist in the first Cocoa code writting years. In fact optional protocol methods were not present in previous objc versions too, everything was required by default.
From that you can actually see that blocks are a simpler way of implementing adhoc delegates, where the receiver of the block declares what parameters are passed to the block, and you are free to do whatever you want with them in your block. And KVO seems to be a less boilerplate way of implementing NSNotification with a more standardized approach to properties, useful for joining the UI created in what previously was called Interface Bilder, and simplifying the "what the hell do I have to do to know when this value changes" which requires a lot of documentation with NSNotification and long constants.
But I still think that there are places for each of these techniques: blocks are nice for mini-adhoc protocols, but would be a serious bother if you need a medium or higher interface area or bidirectional interface, and KVO doesn't help with watching global variables or values outside of a class/object, or stuff you don't want to make part of your public interface.
So my definitive answer is:
1 to 1 simple communication: blocks
1 to 1 complex communication: delegates/protocols
1 to many simple communication: KVO (where possible)
1 to many complex communication: NSNotifications
As always, pick the best tool for each problem, and consider I'm guilty of implementing all of the above in none of the suggested ways!

For the type of task you describe, I feel that NSNotificationCenter is the best option for a generic pattern. The reason is that you can't know, generally, how many external observers there are. The notification system already supports an arbitrary number of observers for an event, whereas the other non-polling options (delegation and blocks) are more typically one-to-one unless you do extra work to support multiple registrations.
As you pointed out yourself, polling is a bad idea if you can avoid it.

In my experience delegation or block callback are the best design choices. Choosing one over the other is mostly dictated by which one is more convenient to code and support for the particular situation. Both are asynchronous. Block callbacks usually reduce the necessity for additional instance variables since blocks capture variables within their scope. Of course for both it's necessary to be aware on which thread the call back is executed or delegate method is called.

I'd go with KVO because you get it for free when using #properties basically.
BUT
I would not recommend using plain KVO. because that will always call - observerValueOfKeyPath... and once you observe multiple keypaths it gets annoying to maintain. you have this mega function with lots of if(keyPath==bla)......
I recommend MAKVONotificationCenter by MikeAsh for this. It also saves you from many a crash when you forget to remove an observer when you dont need it anymore

Related

Use cocoa bindings and threads

I have a few labels bound to a few variables that are modified in other threads via GCD.
Now I've read that cocoa bindings are not thread safe but my app is running fine (the UI updates when the values of the variables are updated in a background thread)
Would it be the correct way to do the calculations in the background thread and if I need to change the variable value make this via
DispatchQueue.main.sync() {
self.variable = newValue
}
?
If cocoa bindings are not thread safe, why I never encountered any crash because of a "read" of the bound UI element while the value was written by a background process?
What is the preferred way to have a value bound to a UI element (via cocoa bindings) and also modify it by async threads?
Thanks!
Yes, if you modify an object that is observed by Cocoa bindings, you should do so only on the main thread, and GCD dispatching the modification to the main thread is a good enough way to do that.
Yes, your app probably works fine most of the time, but that is likely luck based and not actually correct. The problem is that Cocoa bindings are based on Key Value Observation, and KVO notifications are posted on the thread that causes the mutation.
It’s also a complexity problem. As long as your app is relatively simple and fast, there’s much less chance of two threads running afoul of one another. Imagine when your app gets more complex and computationally intensive... and a problem crops up... but by this point you might have hundreds of places where you’re modifying bound properties from multiple threads. It’ll save you grief in the long run to just follow the rules. Use the main thread for updating bound to objects and try to keep bound properties to immutable, value-semantic types.

Which implementations of Condition do not require current thread to hold the lock?

Recently I read some examples from the Chapter 8 of the The Art of Multiprocessor Programming, about “Monitors and Blocking Synchronization” that use the signalAll() of a Condition object, without the acquisition of the lock associated with that Condition.
Surprisingly I did not find any fix for those examples in the book’s errata. Moreover they propose a correction for the example of figure 8.12 of a FifoReadWriteLock, but they keep using the signalAll() without the lock held. That perturbed me and I tried to find other considerations about these examples to understand the reasons why these Java examples were written in this way.
For instance, the answer to the question “How does a read-write mutex/lock work?” shows the same example of the implementation of a FifoReadWriteLock, which implements the writeUnlock() as:
void writeUnlock() {
writer = false;
condition.signalAll();
}
About the absence of the lock acquisition you can read two different reasons:
only use it as pseudo code
some implementation of a condition variable doesn't require that the lock be held to signal.
It is difficult to accept the first argument since the book use examples in Java and explicitly says:
The book uses the Java programming language.
About the second point, I know that the Java API in java.util.concurrent.locks.Condition states for signal() method:
An implementation may (and typically does) require that the current thread hold the lock associated with this Condition when this method is called.
If "an implementation may" only, that means that it is NOT mandatory. Yet, to the best of my knowledge I don’t find any implementation that does NOT fulfill this requirement. So I would like to know which implementations of Java Condition do not require current thread to hold the lock?
I'm not aware of any Condition implementation in the JDK that allows waiting or signaling without owning the monitor at the same time.
Practically all of the java.util.concurrent classes rely on AbstractQueuedSynchronizer which establishes the same contract as the built-in monitor methods wait()/notify()/notifyAll() for the condition variables it provides, i.e. it requires owning the internal lock in order to allow calling await()/signal()/signalAll().
If you try a simple example using the proposed FifoReadWriteLock, you'll find that it spews a serious amount of IllegalMonitorStateExceptions courtesy of its writeUnlock() method. These exceptions disappear if you apply the lock-try-finally approach from the other methods.
While indeed owning the monitor is not absolutely required to wait or signal, often it's the preferable approach, as it saves you from racy condition reads, it shouldn't be too costly as the hand-off between the internal wait sets of the same monitor can still be done fairly efficiently, and because most often you need it for both signaling and scheduling instead of just signaling.

How should I handle mutable state in Clojure in this case?

I'm fairly new to Clojure and LISPs in general, so excuse me in advance if this question sounds a bit silly. I've recently created a turn-based videogame in Java in a MVC fashion, with a thread in charge of the graphic loop (so, updating the geometric state of graphic entities on screen at a fixed rate), and a second thread in charge of handling the logic state of the game; it acted pretty much like a daemon: "sleeping" in the background unless requested to do something (elaborate user input), and then delivering a "change log" to the graphic thread so that it could render the changes made to the logic state. So the game world was not "shared" at all: only the logic thread had access to it, and the graphic thread's only duty was to apply changes to the rendering after an initialization phase and when a new a changed log arrived from the logic thread.
I read that Clojure has vars, refs and atoms. In such a scenario, which one of these identities should I use to store my game world state in the logic thread in Clojure?
In your case, no concurrent access is required, so any option is valid.
ref is a overshoot for this problem. var is not typically used in such a scenario (usually var rebinding is used for configurable parameters, instead of the business logic in your case). So atom should be fine.
EDIT: (elaboration on var)
var, when declared as ^:dynamic (and usually *earmuffed*), is thread-local. It can have a root binding, and each thread can rebind it to a new thread-local value. So typical uses of var you can see in clojure code repo, are *warn-on-reflection*, *unchecked-math*, etc. They mostly tune the behavior of our code somehow.
Since you have only one thread that works on the "board" data, it's OK to use var anyway, but it would look a bit weird to me. I become a bit upset when seeing a var be changed so often. :)

How to handle serialization when using a worker thread from wicket?

In our wicket application I need to start a long-running operation. It will communicate with an external device and provide a result after some time (up to a few minutes).
Java-wise the long running operation is started by a method where I can provide a callback.
public interface LegacyThingy {
void startLegacyWork(WorkFinished callback);
}
public interface WorkFinished {
public void success(Whatever ...);
// failure never happens
}
On my Wicket Page I plan to add an Ajax Button to invoke startLegacyWork(...) providing an appropriate callback. For the result I'd display a panel that polls for the result using an AbstractTimerBehavior.
What boggles my mind is the following problem:
To keep state Wicket serializes the component tree along with the data, thus the data needs to be wrapped in serializable models (or detachable models).
So to keep the "connection" between the result panel and the WorkFinished callback I'd need some way to create a link between the "we serialize everything" world of Wicket and the "Hey I'm a Java Object and nobody manages my lifetime" world of the legacy interface.
Of course I could store ongoing operations in a kind of global map and use a Wicket detachable model that looks them up by id ... but that feels dirty and I don't assume that's the correct way. (It opens up a whole can of worms regarding lifetime of such things).
Or I'm looking at a completly wrong angle on how to do long running operations from wicket?
I think the approach with the global map is good. Wicket also uses something similar internally - org.apache.wicket.protocol.http.StoredResponsesMap. This is a special map that keeps the generated responses for REDIRECT_TO_BUFFER strategy. It has the logic to keep the entries for at most some pre-configured duration and also can have upper limit of entries.

Does WinRT still have the same old UI threading restrictions?

In WinForms, pretty much all your UI is thread-specific. You have to use [STAThread] so that the common dialogs will work, and you can't (safely) access a UI element from any thread other than the one that created it. From what I've heard, that's because that's just how Windows works -- window handles are thread-specific.
In WPF, these same restrictions were kept, because ultimately it's still building on top of the same Windows API, still window handles (though mostly just for top-level windows), etc. In fact, WPF even made things more restrictive, because you can't even access things like bitmaps across threads.
Now along comes WinRT, a whole new way of accessing Windows -- a fresh, clean slate. Are we still stuck with the same old threading restrictions (specifically: only being able to manipulate a UI control from the thread that created it), or have they opened this up?
I would expect it to be the same model - but much easier to use, at least from C# and VB, with the new async handling which lets you write a synchronous-looking method which just uses "await" when it needs to wait for a long-running task to complete before proceeding.
Given the emphasis on making asynchronous code easier to write, it would be surprising for MS to forsake the efficiency of requiring single-threaded access to the UI at the same time.
The threading model is identical. There is still a notion of single threaded and multi-threaded apartments (STA/MTA), it must be initialized by a call to RoInitialize. Which behaves very much like CoInitialize in name, argument and error returns. The user interface thread is single threaded, confirmed at 36:00 in this video.
The HTML/CSS UI model is inherently single threaded (until the advent of web workers recently, JS didn't support threads). Xaml is also single threaded (because it's really hard for developers to write code to a multithreaded GUI).
The underlying threading model does have some key differences. When your application starts, an ASTA (Application STA) is created to run your UI code as I showed in the talk. This ASTA does not allow reentrancy - you will not receive unrelated calls while making an outgoing call. This is a significant difference from STAs.
You are allowed to create async workitems - see the Windows.System.Threadpool namespace. These workitem threads are automatically initialized to MTA. As Larry mentioned, webworkers are the JS equivalent concept.
Your UI components are thread affined. See the Windows.UI.Core.CoreDispatcher class for information on how to execute code on the UI thread. You can check out the threading sample for some example code to update the UI from an async operation.
Things are different in pretty important ways.
While it's true the underlying threading model is the same, your question is generally related to how logical concurrency works with UI, and with respect to this what developers see in Windows 8 will be new.
As you mention most dialogs previously blocked. For Metro apps many UI components do not block all. Remember the talk of WinRT being asynchronous? It applies to UI components also.
For example this .NET 4 code will not necessarily kill your harddrive because the UI call blocks on Show (C# example):
bool formatHardDrive = true;
if (MessageBox.Show("Format your harddrive?") == NO)
formatHardDrive = false;
if (formatHardDrive == true)
Format();
With Windows 8 Metro many UI components like Windows.UI.Popups.MessageDialog, are by default Asynchronous so the Show call would immediately (logically) fall through to the next line of code before the user input is retrieved.
Of course there is an elegant solution to this based on the await/promise design patterns (Javascript example):
var md = Windows.UI.Popups.MessageDialog("Hello World!");
md.showAsync().then(function (command) {
console.log("pressed: " + command.label); });
The point is that while the threading model doesn't change, when most people mention UI and threading they are thinking about logical concurrency and how it affects the programming model.
Overall I think the asynchronous paradigm shift is a positive thing. It requires a bit of a shift in perspective, but it's consistent with the way other platforms are evolving on both the client and server sides.

Resources