<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB"><generator uri="https://jekyllrb.com/" version="4.1.1">Jekyll</generator><link href="https://lnj.gitlab.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://lnj.gitlab.io/" rel="alternate" type="text/html" hreflang="en-GB" /><updated>2022-10-15T16:58:00+02:00</updated><id>https://lnj.gitlab.io/feed.xml</id><title type="html">Linus Jahn</title><author><name>Linus Jahn</name><email>lnj@kaidan.im</email></author><entry><title type="html">Runnning lambda functions on a specific thread with Qt</title><link href="https://lnj.gitlab.io/post/running-lambdas-on-a-thread-with-qt/" rel="alternate" type="text/html" title="Runnning lambda functions on a specific thread with Qt" /><published>2022-10-15T16:00:00+02:00</published><updated>2022-10-15T16:00:00+02:00</updated><id>https://lnj.gitlab.io/post/running-lambdas-on-a-thread-with-qt</id><content type="html" xml:base="https://lnj.gitlab.io/post/running-lambdas-on-a-thread-with-qt/"><![CDATA[<p>Recently I’ve worked a lot with multithreading and wanted to share a very
simple but useful tool.
However, Qt-experts won’t be surprised.</p>

<p><strong>TL;DR</strong>: The final solution can be found <a href="#executing-a-lambda-on-a-qthread">below</a>.</p>

<h2 id="calling-functions-from-another-thread-with-signals">Calling functions from another thread with signals</h2>

<p>When I started to work with multithreading in Qt, I did all thread communication
with signals and slots, because that was the only simple way I knew.
I called functions from another thread using additional signals.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Manager</span> <span class="o">:</span> <span class="k">public</span> <span class="n">QObject</span>
<span class="p">{</span>
    <span class="n">Q_OBJECT</span>
<span class="nl">public:</span>
    <span class="kt">void</span> <span class="n">action</span><span class="p">(</span><span class="k">const</span> <span class="n">QString</span> <span class="o">&amp;</span><span class="n">parameter</span><span class="p">);</span>
    <span class="n">Q_SIGNAL</span> <span class="kt">void</span> <span class="n">actionRequested</span><span class="p">(</span><span class="k">const</span> <span class="n">QString</span> <span class="o">&amp;</span><span class="n">parameter</span><span class="p">);</span>
<span class="p">};</span>
</code></pre></div></div>
<p>If <code class="language-plaintext highlighter-rouge">Manager</code> runs on thread A you can’t just call <code class="language-plaintext highlighter-rouge">action()</code> of course when
you’re operating on thread B.
However, you can <code class="language-plaintext highlighter-rouge">emit manager-&gt;actionRequested(parameter)</code> and Qt will call
the connected slot (<code class="language-plaintext highlighter-rouge">action()</code>) on thread A using a
<a href="https://doc.qt.io/qt-6/qt.html#ConnectionType-enum">Qt::QueuedConnection</a>.</p>

<p>This approach has two big issues though:</p>
<ol>
  <li>You need to create weird signals for every function you want to call from
another thread.</li>
  <li>You can’t handle the results.</li>
</ol>

<p>Now there are of course solutions to point 2, you can i.e. create another
requested-signal on the calling object and call back, but your code will get
much harder to understand.</p>

<p>It gets even worse if there are multiple places from where a function needs to
be called.
How do you know which callback to execute then?</p>

<p>I also knew about the old-variant of <code class="language-plaintext highlighter-rouge">QMetaObject::invokeMethod</code> which
essentially has the same result handling problem, but additionally isn’t even
checked at compile-time.</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">QMetaObject</span><span class="o">::</span><span class="n">invokeMethod</span><span class="p">(</span><span class="n">manager</span><span class="p">,</span> <span class="s">"action"</span><span class="p">,</span> <span class="n">Qt</span><span class="o">::</span><span class="n">QueuedConnection</span><span class="p">,</span>
                          <span class="n">Q_ARG</span><span class="p">(</span><span class="n">QString</span><span class="p">,</span> <span class="n">parameter</span><span class="p">));</span>
</code></pre></div></div>

<h2 id="executing-a-lambda-on-a-qthread">Executing a lambda on a QThread</h2>

<p>I always wanted a solution that would allow to execute a lambda with captured
variables as that would solve all of my issues.
At some point I had the idea to create one signal/slot pair with a
<code class="language-plaintext highlighter-rouge">std::function&lt;void()&gt;</code> parameter to do that, but it’s even easier.
Since Qt 5.10 there’s a new version of <code class="language-plaintext highlighter-rouge">QMetaObject::invokeMethod()</code> that can
do exactly what I needed.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">auto</span> <span class="n">parameter</span> <span class="o">=</span> <span class="n">QStringLiteral</span><span class="p">(</span><span class="s">"Hello"</span><span class="p">);</span>
<span class="n">QMetaObject</span><span class="o">::</span><span class="n">invokeMethod</span><span class="p">(</span><span class="n">otherThreadsObject</span><span class="p">,</span> <span class="p">[</span><span class="o">=</span><span class="p">]</span> <span class="p">{</span>
    <span class="n">qDebug</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="s">"Hello from otherThreadsObject's thread"</span> <span class="o">&lt;&lt;</span> <span class="n">parameter</span><span class="p">;</span>
<span class="p">});</span>
</code></pre></div></div>

<p><strong>Note</strong>: You can’t use a <a href="https://doc.qt.io/qt-6/qthread.html">QThread</a> object as argument here, because
the QThread object itself lives in the thread where it has been created.</p>

<p>I personally don’t like the name <code class="language-plaintext highlighter-rouge">QMetaObject::invokeMethod</code>, so I added an
alias to my projects:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">Function</span><span class="p">&gt;</span>
<span class="k">auto</span> <span class="nf">runOnThread</span><span class="p">(</span><span class="n">QObject</span> <span class="o">*</span><span class="n">targetObject</span><span class="p">,</span> <span class="n">Function</span> <span class="n">function</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">QMetaObject</span><span class="o">::</span><span class="n">invokeMethod</span><span class="p">(</span><span class="n">targetObject</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">function</span><span class="p">));</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The result handling as a caller also works pretty well:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">runOnThread</span><span class="p">(</span><span class="n">object</span><span class="p">,</span> <span class="p">[</span><span class="k">this</span><span class="p">,</span> <span class="n">object</span><span class="p">]</span> <span class="p">{</span>
    <span class="c1">// on object's thread</span>
    <span class="k">auto</span> <span class="n">value</span> <span class="o">=</span> <span class="n">object</span><span class="o">-&gt;</span><span class="n">action</span><span class="p">();</span>

    <span class="n">runOnThread</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="p">[</span><span class="n">value</span><span class="p">]()</span> <span class="p">{</span>
        <span class="c1">// on caller's thread again</span>
        <span class="n">qDebug</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="s">"Calculated result:"</span> <span class="o">&lt;&lt;</span> <span class="n">value</span><span class="p">;</span>
    <span class="p">});</span>
<span class="p">});</span>
</code></pre></div></div>

<p>One could only complain that all your code needs to be indented deeper each
time you call <code class="language-plaintext highlighter-rouge">runOnThread()</code>.
However, that could potentially be solved using C++20 coroutines.</p>]]></content><author><name>Linus Jahn</name><email>lnj@kaidan.im</email></author><category term="Qt" /><summary type="html"><![CDATA[Recently I’ve worked a lot with multithreading and wanted to share a very simple but useful tool. However, Qt-experts won’t be surprised.]]></summary></entry><entry><title type="html">Multithreaded database access with QtSql</title><link href="https://lnj.gitlab.io/post/multithreaded-databases-with-qtsql/" rel="alternate" type="text/html" title="Multithreaded database access with QtSql" /><published>2021-06-10T00:15:00+02:00</published><updated>2021-06-10T00:15:00+02:00</updated><id>https://lnj.gitlab.io/post/multithreaded-databases-with-qtsql</id><content type="html" xml:base="https://lnj.gitlab.io/post/multithreaded-databases-with-qtsql/"><![CDATA[<p><a href="/post/async-databases-with-qtsql/">Last time</a>, we had a look at how to make the database access asynchronous with <a href="https://doc.qt.io/qt-6/qfuture.html">QFutures</a>.
Our solution was to use a one thread <a href="https://doc.qt.io/qt-6/qthreadpool.html">QThreadPool</a> with <a href="https://doc.qt.io/qt-6/qtconcurrent.html#run-1">QtConcurrent</a>.
That works pretty well for most of the use cases,
but as mentioned previously there are some cases where you might want to use multiple threads in parallel to access the database.
That case may be some sort of service, but it of course also works for all other kinds of applications.</p>

<p>However you should also be aware of the disadvantages of having multiple database threads:</p>
<ol>
  <li>Creating many database connections is going to cost you a lot of memory. This might be a point on weaker desktop computers or mobile devices.</li>
  <li>If you’ve only got a modest amount of queries to be executed it might even be a bit slower since you can’t reuse prepared queries across threads.
Also database connection creation doesn’t come without any costs.</li>
</ol>

<p>In the end you should test whether the gained performance improvements are
actually relevant and whether they outweigh the memory usage.
You should also examine how well your database driver handles multithreading,
e.g. sqlite can always only commit one transaction at a time.
The good news is that at least the code doesn’t get complicated.</p>

<h2 id="the-solution">The solution</h2>

<p>What we currently have got is a QThreadPool with only one thread.
That is because the database connections aren’t able to handle queries from
different threads, so we can’t just increase the maximum thread count.</p>

<p>So to fix this we need to create one database connection per thread.
There’s just one problem: the thread pool doesn’t tell us when and which thread
it’s creating or destructing, so we don’t know when we need to create the
database connection and when to remove it again.
Fortunately for us Qt has got a ready-made <a href="https://doc.qt.io/qt-6/qthreadstorage.html">thread storage</a> for exactly this kind of issue.
It works like this:</p>
<ul>
  <li>There’s a global static QThreadStorage</li>
  <li>On every thread you can check whether the storage contains a value for this thread and get or set it.</li>
  <li>When any QThread exits the thread storage automatically destructs the content for the thread.
The thread storage takes ownership of the objects, so this also works with heap-allocated objects.</li>
</ul>

<p>We’re going to use an extra class for the thread storage since we manually need to create and delete the database connection.</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">DatabaseConnection</span>
<span class="p">{</span>
    <span class="n">Q_DISABLE_COPY</span><span class="p">(</span><span class="n">DatabaseConnection</span><span class="p">)</span>
<span class="nl">public:</span>
    <span class="n">DatabaseConnection</span><span class="p">()</span>
        <span class="o">:</span> <span class="n">m_name</span><span class="p">(</span><span class="n">QString</span><span class="o">::</span><span class="n">number</span><span class="p">(</span><span class="n">QRandomGenerator</span><span class="o">::</span><span class="n">global</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">generate</span><span class="p">(),</span> <span class="mi">36</span><span class="p">))</span>
    <span class="p">{</span>
        <span class="k">auto</span> <span class="n">database</span> <span class="o">=</span> <span class="n">QSqlDatabase</span><span class="o">::</span><span class="n">addDatabase</span><span class="p">(</span><span class="n">QStringLiteral</span><span class="p">(</span><span class="s">"QSQLITE"</span><span class="p">),</span> <span class="n">m_name</span><span class="p">);</span>
        <span class="n">database</span><span class="p">.</span><span class="n">setDatabaseName</span><span class="p">(</span><span class="s">"/home/me/data.sqlite"</span><span class="p">);</span>
        <span class="n">database</span><span class="p">.</span><span class="n">open</span><span class="p">();</span>
    <span class="p">}</span>

    <span class="o">~</span><span class="n">DatabaseConnection</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="n">QSqlDatabase</span><span class="o">::</span><span class="n">removeDatabase</span><span class="p">(</span><span class="n">m_name</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="n">QSqlDatabase</span> <span class="n">database</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="n">QSqlDatabase</span><span class="o">::</span><span class="n">database</span><span class="p">(</span><span class="n">m_name</span><span class="p">);</span>
    <span class="p">}</span>

<span class="nl">private:</span>
    <span class="n">QString</span> <span class="n">m_name</span><span class="p">;</span>
<span class="p">};</span>
</code></pre></div></div>

<p>An object of this class will automatically create a new database connection and
remove it as soon as it’s destroyed. Two things are important here:</p>

<ul>
  <li>Each <a href="https://doc.qt.io/qt-6/qsqldatabase.html">QSqlDatabase</a> needs to have a unique name.
In this case we generate a name consisting out of random alphanumerical characters, but there’re
also other solutions.
It’s just important that the name is unique.</li>
  <li>The QSqlDatabase isn’t stored as this would otherwise cause trouble when calling <code class="language-plaintext highlighter-rouge">QSqlDatabase::removeDatabase()</code>.</li>
</ul>

<p>Now we’ll see how to execute queries with the new code, but first let’s have a look at our current code:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">QFuture</span><span class="o">&lt;</span><span class="n">QList</span><span class="o">&lt;</span><span class="n">User</span><span class="o">&gt;&gt;</span> <span class="n">Database</span><span class="o">::</span><span class="n">fetchUsers</span><span class="p">()</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="n">QtConcurrent</span><span class="o">::</span><span class="n">run</span><span class="p">(</span><span class="n">m_pool</span><span class="p">,</span> <span class="p">[</span><span class="k">this</span><span class="p">]()</span> <span class="p">{</span>
        <span class="n">QSqlQuery</span> <span class="n">query</span><span class="p">(</span><span class="n">QSqlDatabase</span><span class="o">::</span><span class="n">database</span><span class="p">(</span><span class="s">"main-connection"</span><span class="p">));</span>
        <span class="n">query</span><span class="p">.</span><span class="n">exec</span><span class="p">(</span><span class="s">"SELECT * FROM users"</span><span class="p">);</span>

        <span class="n">QList</span><span class="o">&lt;</span><span class="n">User</span><span class="o">&gt;</span> <span class="n">users</span><span class="p">;</span>
        <span class="k">while</span> <span class="p">(</span><span class="n">query</span><span class="p">.</span><span class="n">next</span><span class="p">())</span> <span class="p">{</span>
            <span class="c1">// ...</span>
        <span class="p">}</span>
        <span class="k">return</span> <span class="n">users</span><span class="p">;</span>
    <span class="p">});</span>
<span class="p">}</span>
</code></pre></div></div>
<p>We now need to use the correct database connection on each thread and also need
to create them if necessary.</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// the storage for the database connection for each thread</span>
<span class="k">static</span> <span class="n">QThreadStorage</span><span class="o">&lt;</span><span class="n">DatabaseConnection</span> <span class="o">*&gt;</span> <span class="n">databaseConnections</span><span class="p">;</span>

<span class="n">QSqlDatabase</span> <span class="n">Database</span><span class="o">::</span><span class="n">currentDatabase</span><span class="p">()</span>
<span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">databaseConnections</span><span class="p">.</span><span class="n">hasLocalData</span><span class="p">())</span> <span class="p">{</span>
        <span class="n">databaseConnections</span><span class="p">.</span><span class="n">setLocalData</span><span class="p">(</span><span class="k">new</span> <span class="n">DatabaseConnection</span><span class="p">());</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">databaseConnections</span><span class="p">.</span><span class="n">localData</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">database</span><span class="p">();</span>
<span class="p">}</span>

<span class="n">QFuture</span><span class="o">&lt;</span><span class="n">QList</span><span class="o">&lt;</span><span class="n">User</span><span class="o">&gt;&gt;</span> <span class="n">Database</span><span class="o">::</span><span class="n">fetchUsers</span><span class="p">()</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="n">QtConcurrent</span><span class="o">::</span><span class="n">run</span><span class="p">(</span><span class="n">m_pool</span><span class="p">,</span> <span class="p">[</span><span class="k">this</span><span class="p">]()</span> <span class="p">{</span>
        <span class="n">QSqlQuery</span> <span class="n">query</span><span class="p">(</span><span class="n">currentDatabase</span><span class="p">());</span>
        <span class="n">query</span><span class="p">.</span><span class="n">exec</span><span class="p">(</span><span class="s">"SELECT * FROM users"</span><span class="p">);</span>

        <span class="n">QList</span><span class="o">&lt;</span><span class="n">User</span><span class="o">&gt;</span> <span class="n">users</span><span class="p">;</span>
        <span class="k">while</span> <span class="p">(</span><span class="n">query</span><span class="p">.</span><span class="n">next</span><span class="p">())</span> <span class="p">{</span>
            <span class="c1">// ...</span>
        <span class="p">}</span>
        <span class="k">return</span> <span class="n">users</span><span class="p">;</span>
    <span class="p">});</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The <code class="language-plaintext highlighter-rouge">open()</code> function from our previous version isn’t needed anymore and can be
removed, because this is now done in our <code class="language-plaintext highlighter-rouge">DatabaseConnection</code> class.
What’s still left to do is to adjust the thread pool settings in the constructor
of our Database class:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// thread limit (default: number of system threads)</span>
<span class="n">m_pool</span><span class="p">.</span><span class="n">setMaxThreadCount</span><span class="p">(</span><span class="mi">4</span><span class="p">);</span>
<span class="c1">// unused threads are destroyed after 2 minutes (default: 30s)</span>
<span class="n">m_pool</span><span class="p">.</span><span class="n">setExpiryTimeout</span><span class="p">(</span><span class="mi">120000</span><span class="p">);</span>
</code></pre></div></div>
<p>Thread creation and deletion is time-consuming, so you might want to choose an
even higher expiry timeout here.
On the other hand you might still want to save memory when the application is inactive.
If you don’t care about the memory consumption, you can also disable the thread
expiry (setting it to <code class="language-plaintext highlighter-rouge">-1</code>), that will avoid any recreation of database connections.</p>

<p>And basically this is it! The queries are distributed on multiple threads and are executed in parallel now!</p>

<p>There’re just some smaller things that don’t work like before anymore.
We will take a look at two important issues and see how we can solve them.</p>

<h2 id="table-creation--database-migrations">Table creation &amp; database migrations</h2>

<p>In many cases you want your application to take care of table creations and
database migrations.
The database migrations you might already have written are fine and don’t need
to be touched, but there’s one thing we need to pay attention to now:
no other query must be started until all tables have been created correctly, so
no errors are produced.</p>

<p>There are probably many ways of fixing this problem straightforwardly, here is one way:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Database</span>
<span class="p">{</span>
    <span class="c1">// ...</span>
<span class="nl">private:</span>
    <span class="c1">// creates a query and ensures that the tables are ready</span>
    <span class="n">QSqlQuery</span> <span class="n">createQuery</span><span class="p">();</span>
    <span class="c1">// executes database migrations to create all tables</span>
    <span class="kt">void</span> <span class="n">createTables</span><span class="p">();</span>

    <span class="n">QMutex</span> <span class="n">m_tableCreationMutex</span><span class="p">;</span>
    <span class="kt">bool</span> <span class="n">m_tablesCreated</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="p">};</span>
</code></pre></div></div>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">QSqlQuery</span> <span class="n">Database</span><span class="o">::</span><span class="n">createQuery</span><span class="p">()</span>
<span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">m_tablesCreated</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">createTables</span><span class="p">();</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">QSqlQuery</span><span class="p">(</span><span class="n">currentDatabase</span><span class="p">());</span>
<span class="p">}</span>
</code></pre></div></div>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="n">Database</span><span class="o">::</span><span class="n">createTables</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">QMutexLocker</span> <span class="n">locker</span><span class="p">(</span><span class="o">&amp;</span><span class="n">m_tableCreationMutex</span><span class="p">);</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">m_tablesCreated</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span><span class="p">;</span>
    <span class="p">}</span>
    
    <span class="n">QSqlQuery</span> <span class="n">query</span><span class="p">(</span><span class="n">currentDatabase</span><span class="p">());</span>
    <span class="n">query</span><span class="p">.</span><span class="n">exec</span><span class="p">(</span><span class="s">"CREATE TABLE IF NOT EXISTS ..."</span><span class="p">);</span>

    <span class="n">m_tablesCreated</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>If you’re using <code class="language-plaintext highlighter-rouge">createQuery()</code> everywhere to create queries, it’s now always
safe that all database migrations have been done already.</p>

<h2 id="reusing-queries">Reusing queries</h2>

<p>Queries can be reused in order to avoid that the SQL query string needs to be
parsed every time.
In a single-threaded environment we could use static QSqlQueries like this:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">static</span> <span class="k">auto</span> <span class="n">query</span> <span class="o">=</span> <span class="p">[]()</span> <span class="p">{</span>
    <span class="c1">// this is only executed once</span>
    <span class="n">QSqlQuery</span> <span class="n">query</span> <span class="o">=</span> <span class="n">createQuery</span><span class="p">();</span>
    <span class="n">query</span><span class="p">.</span><span class="n">prepare</span><span class="p">(</span><span class="s">"SELECT * FROM users WHERE id = :1"</span><span class="p">);</span>
    <span class="k">return</span> <span class="n">query</span><span class="p">;</span>
<span class="p">}();</span>

<span class="n">query</span><span class="p">.</span><span class="n">addBindValue</span><span class="p">(</span><span class="n">userId</span><span class="p">);</span>
<span class="n">query</span><span class="p">.</span><span class="n">exec</span><span class="p">();</span>

<span class="c1">// ...</span>
</code></pre></div></div>
<p>This way the query is reused and the query is only parsed once. If this query is
executed very frequently this significantly increases the performance,
but also (guess what) consumes more memory.</p>

<p>And again, this needs some adjustments to work with multithreading since the
queries can’t be shared between different threads of course.</p>

<p><em><strong>C++11</strong> to the rescue!</em> C++11 introduced a new keyword <code class="language-plaintext highlighter-rouge">thread_local</code> and this
at least makes it possible to easily reuse the query for each thread.
The code remained exactly the same, except there’s now a little new <code class="language-plaintext highlighter-rouge">thread_local</code>,
which ensures that each thread is going to have its own query:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">thread_local</span> <span class="k">static</span> <span class="k">auto</span> <span class="n">query</span> <span class="o">=</span> <span class="p">[]()</span> <span class="p">{</span>
    <span class="c1">// this is only executed once on each thread</span>
    <span class="n">QSqlQuery</span> <span class="n">query</span> <span class="o">=</span> <span class="n">createQuery</span><span class="p">();</span>
    <span class="n">query</span><span class="p">.</span><span class="n">prepare</span><span class="p">(</span><span class="s">"SELECT * FROM users WHERE id = :1"</span><span class="p">);</span>
    <span class="k">return</span> <span class="n">query</span><span class="p">;</span>
<span class="p">}();</span>

<span class="n">query</span><span class="p">.</span><span class="n">addBindValue</span><span class="p">(</span><span class="n">userId</span><span class="p">);</span>
<span class="n">query</span><span class="p">.</span><span class="n">exec</span><span class="p">();</span>

<span class="c1">// ...</span>
</code></pre></div></div>
<p>But of course keep in mind that this is only useful if a query is executed
frequently, otherwise you just need more memory, especially since the query is
cached for each thread now.</p>

<p>I hope I could help you with that. Feel free to comment if you’ve got any
other solutions or ideas in mind or in production!</p>]]></content><author><name>Linus Jahn</name><email>lnj@kaidan.im</email></author><category term="Qt" /><summary type="html"><![CDATA[Last time, we had a look at how to make the database access asynchronous with QFutures. Our solution was to use a one thread QThreadPool with QtConcurrent. That works pretty well for most of the use cases, but as mentioned previously there are some cases where you might want to use multiple threads in parallel to access the database. That case may be some sort of service, but it of course also works for all other kinds of applications.]]></summary></entry><entry><title type="html">New comment system</title><link href="https://lnj.gitlab.io/post/new-comment-system/" rel="alternate" type="text/html" title="New comment system" /><published>2021-05-25T14:00:00+02:00</published><updated>2021-05-25T14:00:00+02:00</updated><id>https://lnj.gitlab.io/post/new-comment-system</id><content type="html" xml:base="https://lnj.gitlab.io/post/new-comment-system/"><![CDATA[<p>Hello, I just added a comment system to my blog. Feel free to try it out below. :)
Thanks go to <a href="https://jbbgameich.github.io/">JBB</a> for writing &amp; hosting the system.
It’s privacy friendly, requires no login or email verfication and gives you the possibility to delete your posts.</p>]]></content><author><name>Linus Jahn</name><email>lnj@kaidan.im</email></author><summary type="html"><![CDATA[Hello, I just added a comment system to my blog. Feel free to try it out below. :) Thanks go to JBB for writing &amp; hosting the system. It’s privacy friendly, requires no login or email verfication and gives you the possibility to delete your posts.]]></summary></entry><entry><title type="html">Asynchronous database access with QtSql</title><link href="https://lnj.gitlab.io/post/async-databases-with-qtsql/" rel="alternate" type="text/html" title="Asynchronous database access with QtSql" /><published>2021-05-25T00:05:00+02:00</published><updated>2021-05-25T00:05:00+02:00</updated><id>https://lnj.gitlab.io/post/async-databases-with-qtsql</id><content type="html" xml:base="https://lnj.gitlab.io/post/async-databases-with-qtsql/"><![CDATA[<p>In the past I’ve always been struggeling with asynchronous and yet simple
database access with <a href="https://doc.qt.io/qt-6/qtsql-index.html">QtSql</a>.
I now came up with a quite nice solution and I hope I can help you with it.</p>

<h2 id="multithreading-in-qt">Multithreading in Qt</h2>

<p>When working with Qt most of the time you do not need to care about threading.
Most things already work asynchronously, they don’t block and there’s no reason
to mess with additional threads. This is the case for network requests via the
<a href="https://doc.qt.io/qt-6/qnetworkaccessmanager.html">QNetworkAccessManager</a> where signals are used (as pretty much
everywhere).
If you’ve got other tasks like hash calculation of large files or image scaling,
then there’s <a href="https://doc.qt.io/qt-6/qtconcurrent.html#run">QtConcurrent::run()</a> for you which will execute a
function on the application’s thread pool.</p>

<p>QtConcurrent uses <a href="https://doc.qt.io/qt-6/qfuture.html">QFutures</a> to report the results. In Qt 5 QFutures
are not very handy (you need a <a href="https://doc.qt.io/qt-6/qfuturewatcher.html">QFutureWatcher</a> to get the
results asynchronously and you manually need to create and delete it).
With Qt 6 this has changed and now there’s a pretty nice
<a href="https://doc.qt.io/qt-6/qfuture.html#then">QFuture::then()</a> function where you can directly pass a lambda
handling the result:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">QtConcurrent</span><span class="o">::</span><span class="n">run</span><span class="p">([]()</span> <span class="p">{</span>
    <span class="c1">// do heavy calculations ...</span>
    <span class="k">return</span> <span class="n">value</span><span class="p">;</span>
<span class="p">}).</span><span class="n">then</span><span class="p">([](</span><span class="n">Result</span> <span class="n">value</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">qDebug</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="s">"Calculation done:"</span> <span class="o">&lt;&lt;</span> <span class="n">value</span><span class="p">;</span>
<span class="p">});</span>
</code></pre></div></div>

<p>This simple way to chain QFutures creates a nice flow in your code.
Instead of having (maybe multiple) slots that all need to be connected, here you
can just write your code directly behind the QtConcurrent::run() call.</p>

<h2 id="databases-and-threading">Databases and threading</h2>

<p>That’s all pretty nice, but it doesn’t work with databases. You can’t just open
a <a href="https://doc.qt.io/qt-6/qsqldatabase.html">QSqlDatabase</a> and execute queries on it via QtConcurrent.
Most (if not all) SQL database drivers are going to complain that you’re using
the database from the wrong thread.
So, what you need to do is creating the database on the same thread as where the
queries are executed. This means we can’t use QtConcurrent (at least not without
some adjustments) since we don’t know on which thread our job is going to be
executed.</p>

<h2 id="solution-1-thread-worker-model-with-signals">Solution #1: Thread-Worker model with signals</h2>

<p>My first idea on how to solve this and how I also did it in the past was
creating a normal QThread and a database worker class running on the thread.
The database is opened on this new thread and all queries are also executed on
it.
Now with this approach we somehow need to trigger queries and receive their
results. Qt offers signals and slots with queued connections for this. My
approach was to create two signals and a slot on the database worker. Let’s look
at an example here:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">DatabaseWorker</span> <span class="o">:</span> <span class="k">public</span> <span class="n">QObject</span>
<span class="p">{</span>
    <span class="n">Q_OBJECT</span>
<span class="nl">public:</span>
    <span class="n">DatabaseWorker</span><span class="p">(</span><span class="n">QObject</span> <span class="o">*</span><span class="n">parent</span> <span class="o">=</span> <span class="nb">nullptr</span><span class="p">);</span>

<span class="nl">signals:</span>
    <span class="kt">void</span> <span class="n">fetchAllUsersRequested</span><span class="p">();</span>
    <span class="kt">void</span> <span class="n">allUsersFetched</span><span class="p">(</span><span class="k">const</span> <span class="n">QList</span><span class="o">&lt;</span><span class="n">User</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">users</span><span class="p">);</span>

<span class="k">private</span> <span class="n">slots</span><span class="o">:</span>
    <span class="kt">void</span> <span class="n">fetchAllUsers</span><span class="p">();</span>
<span class="p">};</span>
</code></pre></div></div>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">DatabaseWorker</span><span class="o">::</span><span class="n">DatabaseWorker</span><span class="p">(</span><span class="n">QObject</span> <span class="o">*</span><span class="n">parent</span><span class="p">)</span>
    <span class="o">:</span> <span class="n">QObject</span><span class="p">(</span><span class="n">parent</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">connect</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">DatabaseWorker</span><span class="o">::</span><span class="n">fetchAllUsersRequested</span><span class="p">,</span>
            <span class="k">this</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">DatabaseWorker</span><span class="o">::</span><span class="n">fetchAllUsers</span><span class="p">);</span>
<span class="p">}</span>

<span class="n">DatabaseWorker</span><span class="o">::</span><span class="n">fetchAllUsers</span><span class="p">()</span>
<span class="p">{</span>
    <span class="c1">// ... do query ..</span>
    <span class="n">emit</span> <span class="n">allUsersFetched</span><span class="p">(</span><span class="n">users</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>If you want to fetch the users, you’d do the following:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">emit</span> <span class="n">database</span><span class="o">-&gt;</span><span class="n">fetchAllUsersRequested</span><span class="p">();</span>
</code></pre></div></div>

<p>As soon as the database has executed the query, it will emit the
<code class="language-plaintext highlighter-rouge">allUsersFetched()</code> signal, which you can handle.</p>

<p>However this approach has some problems:</p>
<ol>
  <li>You need to care about threading manually.</li>
  <li>You need to create signals and connect them for every new function.</li>
  <li>The caller (of <code class="language-plaintext highlighter-rouge">fetchAllUsersRequested()</code>) doesn’t know which request
belonged to the results received from the signal (<code class="language-plaintext highlighter-rouge">allUsersFetched()</code>). This
is not a problem in this case, but as soon as you’ve got multiple requests
at the same time, this will get important.</li>
</ol>

<p>The second point can be workarounded, but the code won’t be nice.</p>

<h2 id="solution-2-qtconcurrent-with-a-one-thread-qthreadpool">Solution #2: QtConcurrent with a one thread QThreadPool</h2>

<p>Using QtConcurrent with QFutures would solve all three problems here, so we
should have a deeper look at QtConcurrent.
In the documentation we can see that QtConcurrent also provides the option to
use a specific <a href="https://doc.qt.io/qt-6/qthreadpool.html">QThreadPool</a> for the execution.</p>

<p>This helps us since with a custom thread pool we can set the maximum thread
count to <code class="language-plaintext highlighter-rouge">1</code> and so this way can guarantee that everything is executed on the same
thread.
QThreadPool automatically deletes threads when they’re unused.
We also need to prevent this, because the used thread of course must not change:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">QThreadPool</span> <span class="n">pool</span><span class="p">;</span>
<span class="c1">// limit to one thread</span>
<span class="n">pool</span><span class="p">.</span><span class="n">setMaxThreadCount</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
<span class="c1">// prevent automatic deletion and recreation</span>
<span class="n">pool</span><span class="p">.</span><span class="n">setExpiryTimeout</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span>
</code></pre></div></div>

<p>This basically already solved our problem.
We now just need to do everything via QtConcurrent and our QThreadPool and we
don’t need to care about threads at all anymore.</p>

<p>Our Database now could look like this:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Database</span> <span class="o">:</span> <span class="k">public</span> <span class="n">QObject</span>
<span class="p">{</span>
    <span class="n">Q_OBJECT</span>
<span class="nl">public:</span>
    <span class="n">QFuture</span><span class="o">&lt;</span><span class="kt">void</span><span class="o">&gt;</span> <span class="n">open</span><span class="p">();</span>

<span class="nl">private:</span>
    <span class="n">QThreadPool</span> <span class="n">m_pool</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">QFuture</span><span class="o">&lt;</span><span class="kt">void</span><span class="o">&gt;</span> <span class="n">Database</span><span class="o">::</span><span class="n">open</span><span class="p">()</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="n">QtConcurrent</span><span class="o">::</span><span class="n">run</span><span class="p">(</span><span class="n">m_pool</span><span class="p">,</span> <span class="p">[]()</span> <span class="p">{</span>
        <span class="k">auto</span> <span class="n">database</span> <span class="o">=</span> <span class="n">QSqlDatabase</span><span class="o">::</span><span class="n">addDatabase</span><span class="p">(</span><span class="s">"QSQLITE"</span><span class="p">,</span> <span class="s">"main-connection"</span><span class="p">);</span>
        <span class="n">database</span><span class="p">.</span><span class="n">setDatabaseName</span><span class="p">(</span><span class="s">"/home/me/data.sqlite"</span><span class="p">);</span>
        <span class="n">database</span><span class="p">.</span><span class="n">open</span><span class="p">();</span>
        <span class="c1">// of course you should do some more checks here to see</span>
        <span class="c1">// whether everything went well :)</span>
    <span class="p">});</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Other queries can be done like this now:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">QFuture</span><span class="o">&lt;</span><span class="n">QList</span><span class="o">&lt;</span><span class="n">User</span><span class="o">&gt;&gt;</span> <span class="n">Database</span><span class="o">::</span><span class="n">fetchUsers</span><span class="p">()</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="n">QtConcurrent</span><span class="o">::</span><span class="n">run</span><span class="p">(</span><span class="n">m_pool</span><span class="p">,</span> <span class="p">[</span><span class="k">this</span><span class="p">]()</span> <span class="p">{</span>
        <span class="n">QSqlQuery</span> <span class="n">query</span><span class="p">(</span><span class="n">QSqlDatabase</span><span class="o">::</span><span class="n">database</span><span class="p">(</span><span class="s">"main-connection"</span><span class="p">));</span>
        <span class="n">query</span><span class="p">.</span><span class="n">exec</span><span class="p">(</span><span class="s">"SELECT * FROM users"</span><span class="p">);</span>

        <span class="n">QList</span><span class="o">&lt;</span><span class="n">User</span><span class="o">&gt;</span> <span class="n">users</span><span class="p">;</span>
        <span class="k">while</span> <span class="p">(</span><span class="n">query</span><span class="p">.</span><span class="n">next</span><span class="p">())</span> <span class="p">{</span>
            <span class="c1">// ...</span>
        <span class="p">}</span>
        <span class="k">return</span> <span class="n">users</span><span class="p">;</span>
    <span class="p">});</span>
<span class="p">}</span>
</code></pre></div></div>

<p>And with Qt 6 you can pretty easily handle the results now:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">database</span><span class="o">-&gt;</span><span class="n">fetchUsers</span><span class="p">().</span><span class="n">then</span><span class="p">([](</span><span class="k">const</span> <span class="n">QList</span><span class="o">&lt;</span><span class="n">User</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">users</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// do something</span>
<span class="p">});</span>
</code></pre></div></div>

<p>Unfortunately with Qt 5 it’s not so nice:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">auto</span> <span class="o">*</span><span class="n">watcher</span> <span class="o">=</span> <span class="k">new</span> <span class="n">QFutureWatcher</span><span class="o">&lt;</span><span class="n">QList</span><span class="o">&lt;</span><span class="n">User</span><span class="o">&gt;&gt;</span><span class="p">();</span>
<span class="n">connect</span><span class="p">(</span><span class="n">watcher</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">QFutureWatcherBase</span><span class="o">::</span><span class="n">finished</span><span class="p">,</span> <span class="p">[</span><span class="n">watcher</span><span class="p">]()</span> <span class="p">{</span>
    <span class="n">QList</span><span class="o">&lt;</span><span class="n">User</span><span class="o">&gt;</span> <span class="n">users</span> <span class="o">=</span> <span class="n">watcher</span><span class="o">-&gt;</span><span class="n">result</span><span class="p">();</span>
    <span class="c1">// do something with the result</span>
    <span class="n">watcher</span><span class="o">-&gt;</span><span class="n">deleteLater</span><span class="p">();</span>
<span class="p">});</span>
<span class="n">watcher</span><span class="o">-&gt;</span><span class="n">setFuture</span><span class="p">(</span><span class="n">database</span><span class="o">-&gt;</span><span class="n">fetchUsers</span><span class="p">());</span>
</code></pre></div></div>

<p>This is not very nice and things can go wrong, you could forget to delete
the QFutureWatcher for example.
Thus, we use a template function to simplify this:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">Handler</span><span class="p">&gt;</span>
<span class="kt">void</span> <span class="nf">await</span><span class="p">(</span><span class="k">const</span> <span class="n">QFuture</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">future</span><span class="p">,</span> <span class="n">QObject</span> <span class="o">*</span><span class="n">context</span><span class="p">,</span> <span class="n">Handler</span> <span class="n">handler</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">auto</span> <span class="o">*</span><span class="n">watcher</span> <span class="o">=</span> <span class="k">new</span> <span class="n">QFutureWatcher</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">context</span><span class="p">);</span>
    <span class="n">QObject</span><span class="o">::</span><span class="n">connect</span><span class="p">(</span><span class="n">watcher</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">QFutureWatcherBase</span><span class="o">::</span><span class="n">finished</span><span class="p">,</span>
                     <span class="n">context</span><span class="p">,</span> <span class="p">[</span><span class="n">watcher</span><span class="p">,</span> <span class="n">handler</span> <span class="p">{</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">handler</span><span class="p">)</span> <span class="p">}]()</span> <span class="p">{</span>
        <span class="n">handler</span><span class="p">(</span><span class="n">watcher</span><span class="o">-&gt;</span><span class="n">result</span><span class="p">());</span>
        <span class="n">watcher</span><span class="o">-&gt;</span><span class="n">deleteLater</span><span class="p">();</span>
    <span class="p">});</span>
    <span class="n">watcher</span><span class="o">-&gt;</span><span class="n">setFuture</span><span class="p">(</span><span class="n">future</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">await</span><span class="p">(</span><span class="n">database</span><span class="o">-&gt;</span><span class="n">fetchUsers</span><span class="p">(),</span> <span class="k">this</span><span class="p">,</span> <span class="p">[](</span><span class="n">QList</span><span class="o">&lt;</span><span class="n">User</span><span class="o">&gt;</span> <span class="n">users</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// do something</span>
<span class="p">});</span>
</code></pre></div></div>
<p>And that already looks much better! :)</p>

<p>We now got a solution with the following features:</p>
<ol>
  <li>A database class running in the main thread. No manual thread management.</li>
  <li>No signals and slots for each new function. Just <code class="language-plaintext highlighter-rouge">QFuture::then</code> / <code class="language-plaintext highlighter-rouge">await</code>.</li>
  <li>Request and result handling can be easily ‘linked’ by using lambda captures.</li>
</ol>

<p>This is a very nice solution for most of the use cases in our applications.</p>

<p>Do we want anything more? – Okay, maybe parallel queries with multiple threads,
for building servers or a high-performing application, but that’s probably
irrelevant in most of the cases.
However, maybe we’ll see this in one of the next blog posts. :)</p>]]></content><author><name>Linus Jahn</name><email>lnj@kaidan.im</email></author><category term="Qt" /><summary type="html"><![CDATA[In the past I’ve always been struggeling with asynchronous and yet simple database access with QtSql. I now came up with a quite nice solution and I hope I can help you with it.]]></summary></entry><entry><title type="html">The perfect ejabberd setup with ansible</title><link href="https://lnj.gitlab.io/post/ejabberd-ansible/" rel="alternate" type="text/html" title="The perfect ejabberd setup with ansible" /><published>2019-01-09T13:00:00+01:00</published><updated>2019-01-09T13:00:00+01:00</updated><id>https://lnj.gitlab.io/post/ejabberd-ansible</id><content type="html" xml:base="https://lnj.gitlab.io/post/ejabberd-ansible/"><![CDATA[<h2 id="previously-on-xmpp-server-setup">Previously on “XMPP server setup”…</h2>

<p>In April last year I setup the <code class="language-plaintext highlighter-rouge">kaidan.im</code> XMPP server with ejabberd. As you would expect I did that
completely manually, so first running <code class="language-plaintext highlighter-rouge">apt get install ejabberd</code>, then editing the config file and
so on. I read the ejabberd documentation in detail to enable all useful features and to get the
nearly perfect server config. I also imported the database from a
<a href="https://jbbgameich.github.io/">friend of mine</a>, who hosted his server (<code class="language-plaintext highlighter-rouge">jbb.ddns.net</code>) on a
Raspberry Pi before.</p>

<p>Then, in July I got a small job to install an XMPP server for the <a href="https://dbjr.de/">DBJR</a>
(Deutscher Bundesjugendring). It was already clear that we’ll first test the XMPP server on a small
(Hetzner) cloud server and later move it to a larger one as the project grows. Besides the internal
server <code class="language-plaintext highlighter-rouge">chat.dbjr.org</code> we also set up the <code class="language-plaintext highlighter-rouge">yochat.eu</code> domain (youth organization chat) to be opened
for free registration later. Because we didn’t want to do all the setup multiple times (and
researching everything after forgetting everything), I came up with the idea of using
<a href="https://www.ansible.com/">ansible</a> to automate everything. The result was nice, but still very
server specific. Later I based on the ansible playbook for moving my own server. Recently I also did
some real abstraction, so now only some config options would need to be changed to get the
chat.dbjr.org-server. On 9th January, I gave a talk about this at the
<a href="https://de.movim.eu/?node/pubsub.movim.eu/berlin-xmpp-meetup/">XMPP Meetup</a>.</p>

<h2 id="how-to-setup-your-own-server">How to setup your own server</h2>

<p>My ansible role is publicly available on my <a href="https://git.kaidan.im/lnj/ansible-role-ejabberd">GitLab instance</a>. I’ll show you how to
use it in this blog post, but we won’t go into details about ansible. The first step is to create a
new ansible playbook for this project (as long as you don’t have one yet). Just create this folder
structure (we’ll talk about the speific files later):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ls myplaybook/ myplaybook/env/ myplaybook/env/host_vars/
myplaybook/:
env/  roles/  mysetup.yml

myplaybook/env/:
myhosts.inventory  host_vars/

myplaybook/env/host_vars/:
myxmppserver.yml
</code></pre></div></div>

<p>Then clone the ejabberd and certbot roles into the <code class="language-plaintext highlighter-rouge">roles</code> folder:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone ssh://git@git.kaidan.im/lnj/ansible-role-ejabberd ejabberd
git clone ssh://git@git.kaidan.im/lnj/ansible-role-certbot certbot
</code></pre></div></div>

<p>After that you should add the target server to the inventory file:</p>
<div class="language-toml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># this is the group name:</span>
<span class="nn">[xmppservers]</span>
<span class="c"># this is the server name (as you would use it when connecting via. ssh); you</span>
<span class="c"># could also write `user@xmpp.server.example`, but it's better to add that info</span>
<span class="c"># to your ~/.ssh/config</span>
<span class="err">myxmppserver</span>
</code></pre></div></div>

<p>Now copy the default configurations of the roles to your host configuration
(remove the three dashes <code class="language-plaintext highlighter-rouge">---</code> from the second file):</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cat </span>roles/ejabberd/defaults/main.yml roles/certbot/defaults/main.yml <span class="o">&gt;</span> <span class="nb">env</span>/host_vars/myxmppserver.yml
</code></pre></div></div>

<p>You can edit that file and adjust everything to your needs. The config options should all be
self-explaining (contact me if they’re not). If you need some advanced options you can just edit the
ejabberd.yml template file in the ejabberd role. So now what’s still missing is an ansible script
(i.e. <code class="language-plaintext highlighter-rouge">mysetup.yml</code>) that will execute the ejabberd role on your server:</p>
<div class="language-yml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>

<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Install ejabberd</span>
  <span class="na">hosts</span><span class="pi">:</span> <span class="s">xmppservers</span> <span class="c1"># this is the group name, you could also specify a single host</span>
  <span class="na">become</span><span class="pi">:</span> <span class="no">true</span>
  <span class="na">roles</span><span class="pi">:</span>
    <span class="pi">-</span> <span class="s">certbot</span>
    <span class="pi">-</span> <span class="s">ejabberd</span>
</code></pre></div></div>

<p>And that’s basically it, you can now execute the playbook on your server using this command:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ansible-playbook <span class="nt">-i</span> <span class="nb">env</span>/myhosts.inventory mysetup.yml
</code></pre></div></div>

<p>If you’re using this, it’ll probably be much easier for you to setup the server (and especially
when moving it to another machine!).</p>]]></content><author><name>Linus Jahn</name><email>lnj@kaidan.im</email></author><category term="XMPP" /><summary type="html"><![CDATA[Previously on “XMPP server setup”…]]></summary></entry><entry><title type="html">QLI-Installer: Installing official Qt-builds from the command line</title><link href="https://lnj.gitlab.io/post/qli-installer/" rel="alternate" type="text/html" title="QLI-Installer: Installing official Qt-builds from the command line" /><published>2018-12-23T20:47:00+01:00</published><updated>2018-12-23T20:47:00+01:00</updated><id>https://lnj.gitlab.io/post/qli-installer</id><content type="html" xml:base="https://lnj.gitlab.io/post/qli-installer/"><![CDATA[<p><b>NOTE: This script is outdated. Have a look at the well-maintained fork of it: <a href="https://github.com/miurahr/aqtinstall">aqtinstall</a></b></p>

<hr />

<p>As you probably know, Qt provides many builds for different systems and
architectures. They can be very useful, if you want to develop with the latest
libraries, even if your distro doesn’t provide them (or if you’re using
Windows/Mac and you got no Qt at all). In my I case I wanted to use the latest
Qt on an LTS CI system. I know that there are PPAs for Ubuntu, however, if you
want to use the Qt for Android builds, there’s really no other way: either you
compile everything yourself or you need to use the official installer.</p>

<p>There’s just one problem: Qt only provides a graphical installer, which can’t be
on a server. This has been a problem for a long time and there are some
workarounds using the Qt scripting interface with a virtual display, but that
workaround isn’t that easy to use and error-prone. You can find an example of
this on <a href="https://stackoverflow.com/a/34032216/4483773">stackoverflow</a>.</p>

<p>Since the Qt Installer basically only lets you select the Qt version and then
downloads &amp; extracts everything, I thought that it couldn’t be too hard to
rewrite that in a simple script. I browsed a bit through the
<a href="https://download.qt.io/online/qtsdkrepository/">Qt installer repository</a> and started to write a python script
that should output the URLs for a specific Qt version. Turns out: the URLs are
not consistent in all Qt versions and they contain long build numbers. To solve
this I needed to parse the <code class="language-plaintext highlighter-rouge">Updates.xml</code> file for each target/version. These
files list all the packages and their dependencies. From these we only need the
main package (it contains most modules as QtCore, QtSql, QtSvg and many more,
only QtCharts and similar are missing) and can ignore its dependencies (it only
depends on the qtcreator, documentation and examples, which we all don’t need
for our purpose).</p>

<p>In the end I came up with a python script that can download and extract you
every Qt version you want (even iOS builds can be downloaded on a Linux host
system, which wasn’t possible before :D). The script (currently) just calls the
p7zip commands for extracting the packages which isn’t optimal, but OK.</p>

<p>So if you would like to use the official Qt builds on a server and don’t want to
argue with the graphical installer, you might want to try my script. It’s
available on my <del>GitLab instance</del> <a href="https://git.sr.ht/~lnj/qli-installer">sourcehut repo</a>.
Here is an example how to use it on debian-based systems:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt <span class="nb">install </span>python3-requests p7zip-full wget

wget https://git.kaidan.im/lnj/qli-installer/raw/master/qli-installer.py
<span class="nb">chmod</span> +x qli-installer.py

./qli-installer.py 5.12.0 linux desktop
</code></pre></div></div>

<p>This will download and extract Qt 5.12.0 to a folder called <code class="language-plaintext highlighter-rouge">5.12.0</code> in your
current directory. You can find more details in the README. If you have any
suggestions or you’ve found a bug (the installer repository format changes from
time to time), please <a href="https://git.kaidan.im/lnj/qli-installer/issues/new">submit an issue</a>.</p>]]></content><author><name>Linus Jahn</name><email>lnj@kaidan.im</email></author><category term="Qt" /><summary type="html"><![CDATA[NOTE: This script is outdated. Have a look at the well-maintained fork of it: aqtinstall]]></summary></entry></feed>