As you might have seen, we are coming close to the most awesome Free/Libre Software conference – Akademy – the one and only place where you can meet a few hundred KDE contributors. It will be held in Berlin as a part and continuation of QtCon.
I’m going to give a talk there about all things that are wrong with the QFuture, and the things that might be fixed in the future (pun intended).
In general, futures are a great concept that allow developers to easily implement asynchronous and concurrent systems. But, why isn’t it the case with QFuture? I’ll try to cover a few things like what is wrong with the idea behind QFuture, what is wrong with its API, should we go for std::future (or boost::future instead and similar.
See you there!
p.s. If you are going to Akademy, you are free to use the above banner in your blogs and such. It is not the official VDG banner (we don’t have the official one yet as far as I know), but Jens likes it so it is almost as if it was the official one. :)
It comes in two different sizes, the regular and the slim one.
Published
in the Prog C++ section,
on 13 July 2016
Berlin is still the city to be in if you are interested in C++ and/or Qt. At least, if you are in Europe and don’t like the idea of flying across the ocean to go to CppCon.
The first conference will be in September, and it will join the KDE, Qt, VideoLAN and FSFE communities. It is a continuation of the Qt Dev Days and Qt World Summit for Europe, and it is called QtCon.
The second conference is becoming a true tradition, even for me, and it stays true to its original name – Meeting C++. It will be in November this time, which is a pitty since Berlin in December is filled with beautiful christmas markets which provided all the Meeting C++ participants great time last few years.
It is strange to talk about improvements when the product does not yet exist, but there are a few important ideas that deviate from original KRunner that I’ve been working on.
I’ve already ported a few of the more important runners in order to be able to test the infrastucture. While doing this, I’ve been able to detect a few deficiencies of the current design. So I decided to go over the design of KRunner and the way it used to generate the results in order to which parts could be improved.
Reusing the results
In the old KRunner, the user would type a query, and the runners would generate the results for that query. Now, if you added another character to the query, the runners would generate all the results for that new query from scratch.
This is suboptimal. When the user types ‘kons’ and gets Konsole as the result, typing ‘o’ should not remove konsole from the list only to add it again because it still matches the input string ‘konso’.
Now each runner can add the whole string it used for matching to the result. So, in the case of Konsole, it could pass something like ‘Konsole - Terminal’. This way, the GUI part of KRunner will be able to tell that this result is still relevant and that it should keep it in the list. Runner that searches for files might even pass a section of the text where the query appears (this might even be useful to show in the UI - like Recoll does).
Merging the results
The second thing that I always found strange is that if two different runners returned the same result, KRunner will show the result twice. Just enter ‘konsole’, and you will get ‘Konsole’ and ‘Run konsole’.
Now, if two runners return the same thing, the results will be combined, and the result will get a higher score. Since the score (or relevance) is a number between 0 and 1, these are combined in a fun math way used in fuzzy logic.
Result owner
The other problem in KRunner is that each runner is tasked to handle the results it has created. This means that you might get different available actions for the same file if it was returned by two different runners.
So, the second change was to rethink what is a result in KRunner.
Instead of each runner owning its result, it will now, by default, only need to explain what the result is. That way, if it is a file, the GUI will know what actions to provide, if it is an application, the GUI will know what actions to provide, etc. If it is something unorthodox, then, and only then, the runner should be asked how to execute it.
When?
It is difficult to predict, but I hope I’ll be able to make a preview version (called ‘Blade’) by the end of July. The current plan is to release it as a separate application – for testing purposes only, and after that I’ll have to go one KRunner feature at a time to make sure it has no obvious regressions.
The worst part is that, thanks to Kai Uwe, KRunner is now a moving target and I’ll have to play catch-up with all the features he adds to main KRunner. :)
In my previous post, I’ve talked about the idea to split KRunner into a few separate processes that will execute the different searching plugins (also known as runners) isolated from one another.
This time, I’m going to talk about the Voy library (framework?) that was born from this idea and that is still evolving to better suit the use-cases of KRunner, while also being general enough for a few more test apps that I build against it.
The Model
The idea is simple – the system should be split into a bunch of components. Each component should follow the UNIX philosophy – do one thing, and do it well. The components need to be isolated in the sense that the only way for two components to interact with each other is by sending messages – no shared memory, no shared data, nothing – just messages.
You can think of it like these components were persons. We don’t know what the next person is thinking about unless he/she tells us.
This approach allows implementing complex systems without any synchronization primitives like mutexes, and if done well, they lift the requirement that all components need to be in the same process or even on the same host. We just need to be able to serialize messages and transfer them over the network.
This model does introduce complexities in other areas – we need to think of the program logic in a slightly different way, but it is worth it.
There are a few libraries that implement this and similar models like the C++ Actor Framework and SObjectizer, but they have a significantly different project aims to this one. Still, they are worth checking out.
The Messaging System
In this model, the messages are crucial, so the most important part of the Voy library is its message handling.
Like in the real life, in order to communicate with others, we either need to know to whom we want to pass information, or we can yell to make sure everybody hears us.
In Voy, this is a bit more granular. Each agent (we will call these isolated components agents from now on) has an address comprised of three components:
the unique id of the host it is running on
a unique id of the process instance it belongs to (called a ‘group’ in Voy)
and a unique id of the agent itself
This way, if we know the address, we can send a targeted message to another agent. We could also choose to send messages to all agents belonging to a specific group, or to all agents located on a specific host. This gives us some control, but it is mostly based on the physical location of the Agent.
Sometimes, we might want to target a specific group of agents that are not in the same location, but still not to spam other agents with messages they do not need.
As an example, imagine a community of software developers working on a huge Free Software project. They are usually located in completely different parts of the world, but they still belong to the same team. They should be able to communicate without agents that are not in that team receiving those messages.
This brought named teams to Voy. While everything else is based on UUIDs, teams have proper names. This means that we are able to split agents into named groups, and they will be able to communicate even if they don’t know the addresses of other team members.
This works similar to mailing lists – I don’t need to know mail addresses of all Plasma developers, but I still can send them an e-mail through the mailing list.
For improved granularity, sending messages to a team can also be limited to a specific host or process instance.