I’ve just upgraded this blog to Jekyll 3.
There were quite a few hurdles along the way, but all should be ok now.
I’ve found three different types of transition issues
(it is cool to look at these in a project I do not upgrade on a daily basis
like Plasma and the rest of the KDE software).
Type 1: Issues that break the build
API for plugins has changed. This means that plugins I wrote
for this blog stopped working (some of them).
This was the most painful one to fix,
since I had to investigate the changes in the plugin system
in a programming language that I really do not like
(Jekyll is written in ruby).
Type 2: Sneaky behaviour changes
The second type of issues
were small changes in behaviour like,
changing how the permalinks are generated,
changing a few things that were lowercase-only to uppercase
These issues were more annoying than the type 1.
With type 1, you know where you are at -
your build is broken, and you need to fix it.
The type 2 you can discover only
by actually checking whether the pages are generated properly or not
(in the end, I diffed the whole generated site to see what were the changes).
Type 3: Ruby GSL
The third issue was not really because of Jekyll upgrade,
but it did appear at the same time.
Ruby GSL library relies on an ancient version of
GNU Scientific Library which even Debian does not use anymore (Debian testing).
And while building the site with jekyll,
you get absolutely no information that your setup is broken.
The build does not crash because of a missing library,
because of incompatible library symbols,
it just keeps building.
And keeps building.
At some point you realize that even ruby is not that slow
and that something is wrong…
While it is nice to get speed improvements and all,
we should pay attention not to break things.
In Plasma, we do create breakages in major releases
because sometimes transitioning
the configuration to the new architecture is hard, or impossible.
I just hope we will not have a good reason to do it again anytime soon. :)
Today, I did the most evil hack I’ve done so far in a real project.
It is not something I plan to keep in the code,
but it is cool enough to be shared.
Do not use something like this. Ever.
I’ve found out that QFuture can contain an exception
in the case something in the asynchronous process failed.
This is nice, because it (even if Qt generally does not like exceptions)
provides a nice error reporting mechanism for asynchronous tasks
The problem is that in order to access the exception,
you need to invoke some of the blocking methods
like result() or waitForFinished().
And I hate methods that block.
Before I propose a patch for QFuture to allow
testing for an exception,
I had to find a way to access this data
without it really being supported.
The exception store is located in a private (pimpled) class in the QFuture.
So, how to access something that is private from the outside?
One possibility is #define private public but that is just overly
crude for my taste.
The second, and much more interesting one comes after realizing that
QFuture is a templated class,
and a templated class is not really closed.
The access restrictions do not apply to different instantiations of
a templated class, so if we can create an instantiation of a method
in QFuture for some class that does not really exist,
and is not used anywhere else in the world,
and we will be able to access its privates.
And, from now on, this instantiation of the method can be used to check
whether a specific future contains an exception.
Everyone talks about the power of templates,
and the possibility to calculate stuff at compile-time.
But they are much more powerful than that. :)
p.s. Yes, it would have been much easier to just roll my own qfuture.h
The idea of having a container for a value that is not yet
present, but will be available sometime in the future
is a powerful one.
it decouples the asynchronous process invocation
from the result handler.
This allows creating nicer asynchronous APIs than the usual approaches.
The Qt library provides a container like this – the QFuture<T>.
And, at the same time, it provides incompatible special-cases containers like
QDBusReply<T> and other Q*Reply classes.
QFuture was meant to be used only in the QtConcurrent library,
and was designed to suit that need –
to wrap operations executed concurrently on multiple threads.
It was moved to QtCore in 5.x,
but apart from the rellocation,
it did not receive much love,
and its design stayed the same.
Issues with waiting
In order to do something with the result,
you need to wait for the future to arrive.
It you do not want to block your main thread,
you need to wait for the future like this:
This makes using QFuture a pain.
I’ve been creating wrappers for this
on multiple occasions,
and realised that I do it often enough
to warrant creating a new library.
Issues with creation
Another issue with QFuture is that Qt does not really use it.
The previously mentioned classes like QDBusReply are a perfect example.
Imagine you are writing an interface library for some
You can make it blocking
which is very bad since the service might take a long time to respond.
You can make it asynchronous by returning QDBusReply
which exposes the implementation detail via the API.
Also a very bad approach.
Or, you can split it into a request slot and a response signal
which is plain ugly to write and use.
If the QFuture<QString> is used instead,
you get exactly what you need
it is asynchronous,
it hides all the implementation details
(the user does not know whether it uses DBus,
executes an external process and returns its output, etc.)
and it is not ugly.
The problem is that Qt does not provide
a way to allow you to convert these different future-like constructs
This is the second reason behind the creation of the AsynQt framework.
What is AsynQt?
The aims of the framework are:
To provide wrappers for common Qt future-like classes
To add methods for easier manipulation of QFutures
I’ve implemented wrappers for the DBus and QProcess.
You can convert the QDBusReply<T> to a QFuture<T> simply by
using the makeFuture template function,
or you can invoke a DBus method and get the QFuture
as the result immediately:
QProcess wrapper is a bit trickier because it has one special feature.
Apart from the process, it receives a function that
allows you to extract the information you want to return from the process,
instead of returning the QFuture<QProcess*>.
Examples are worth more than words:
There are also a few convenience methods for creating simpler futures
makeReadyFuture that creates a future which already contains a value,
makeCanceledFuture that creates a canceled future and
makeDelayedFuture which creates a future that will contain
the specified value after the specified duration of time.
And more will come.
Now, all of the above would not be that useful
if we still had to use the usual QFuture API.
For this reason,
a few new methods are provided –
transform, flatten, cast, continueWith.
I’ll leave the explanation of these for later
(when I add a couple more different ones
that I consider necessary).
At this time, just a few examples:
Pipe or range syntax
The library also supports the pipe syntax.
Instead of calling a transformation on a future directly,
you can also send the future through a pipe to the transformation.
There were some complaints from our Windows people
that it is difficult to build KActivities (on Windows)
due to its usage of boost.
This is just a public service announcement that the library part
is no longer using boost (it was using only boost::optional)
so that this is not a problem anymore if you
build with -DKACTIVITIES_LIBRARY_ONLY flag.
Non-library parts that are meant for not to be used
on Windows will still depend on boost,
and on proper C++ compilers.
P.S. I’ve created a optional_view class. Might be a thing
worth developing further, since we are getting array_view,
I had two reasons to be there.
One was that I was giving a talk on the (functional) reactive programming with Qt.
The second was to help a bit with the organization -
to help people minding the KDE booth,
and to chair a session.
It was a nice opportunity to see some KDE friends I haven’t
seen for a while, since I missed the aKademy this year.
For me, the trip started a few days before the conference,
so I was there in time to join the KDE e.V. board dinner.
We went to a nice place (one of my favourites) in Tiergarten.
As you can see in the picture above,
we left a mark on the wall of the place.
I wasn’t inspired to actually draw anything more involved
than a simple KDE logo, but it shows we were there.
Now, while it is always nice to see other KDE people in-person,
my main reason for being there was the talk.
Strangely enough, even though quite a few people told me that
they have no idea what “reactive” means, the room was packed.
This time I wasn’t really in my element, was overly tired,
but I think it went fine. I’ve had a few people contact me
afterwards with further inquiries about the topic. Unfortunately,
I had to skip Milian’s talk because of that.
The main mistake I kept making this time is not to repeat the audience questions.
I completely forgot that there was no microphone for the audience.
I hope you’ll be able to follow the talk with all the cut-outs of audience talking. :)