<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Roman Podoliaka's blog</title><link>https://www.podoliaka.org/</link><description>Recent content on Roman Podoliaka's blog</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 12 Oct 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://www.podoliaka.org/index.xml" rel="self" type="application/rss+xml"/><item><title>Counting new lines faster, or how to beat wc at its own game</title><link>https://www.podoliaka.org/2025/10/12/newlines/</link><pubDate>Sun, 12 Oct 2025 00:00:00 +0000</pubDate><guid>https://www.podoliaka.org/2025/10/12/newlines/</guid><description>&lt;h1 id="introduction">
 Introduction
 &lt;a class="heading-link" href="#introduction">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h1>
&lt;p>If you haven&amp;rsquo;t heard of &lt;a href="https://github.com/gunnarmorling/1brc" class="external-link" target="_blank" rel="noopener">The One Billion Row Challenge&lt;/a>,
it&amp;rsquo;s a fun contest in which participants are asked to write a computer program that would parse
a one billion line long text file and aggregate that data in the fastest way possible. This,
of course, has very little to do with real life coding, but, nevertheless, it is a highly
entertaining exercise in performance optimization.&lt;/p></description></item><item><title>debuginfod: easier debugging on Linux</title><link>https://www.podoliaka.org/2025/05/19/debuginfod/</link><pubDate>Mon, 19 May 2025 00:00:00 +0000</pubDate><guid>https://www.podoliaka.org/2025/05/19/debuginfod/</guid><description>&lt;h1 id="what-happened">
 What happened
 &lt;a class="heading-link" href="#what-happened">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h1>
&lt;p>Since 2022, popular Linux distros (&lt;a href="https://debuginfod.archlinux.org/" class="external-link" target="_blank" rel="noopener">Arch Linux&lt;/a>,
&lt;a href="https://debuginfod.fedoraproject.org/" class="external-link" target="_blank" rel="noopener">Fedora&lt;/a>, &lt;a href="https://debuginfod.ubuntu.com" class="external-link" target="_blank" rel="noopener">Ubuntu&lt;/a>,
&lt;a href="https://debuginfod.debian.net" class="external-link" target="_blank" rel="noopener">Debian&lt;/a>) have been serving DWARF&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> debug
symbols and the source code for the packages in their repositories using
&lt;a href="https://sourceware.org/elfutils/Debuginfod.html" class="external-link" target="_blank" rel="noopener">debuginfod&lt;/a>.&lt;/p>
&lt;p>debuginfod is a web service that distributes ELF binaries, DWARF debug symbols, and source code
over HTTP. Debuggers, profilers, and other tools can now &lt;em>lazily&lt;/em> fetch that information from a
remote server to help you analyze program crashes, reliably display stack traces, and so on.&lt;/p></description></item><item><title>The perils of temporary object lifetimes in C++</title><link>https://www.podoliaka.org/2023/11/21/cpp-lifetimes/</link><pubDate>Tue, 21 Nov 2023 00:00:00 +0000</pubDate><guid>https://www.podoliaka.org/2023/11/21/cpp-lifetimes/</guid><description>&lt;p>The other day my junior colleague asked me to help him troubleshoot a failing unit test: the
actual value of a protocol buffer string field did not match&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> the expected value, and he
couldn&amp;rsquo;t figure out why. I&amp;rsquo;m not allowed to share that code, but it can be summarized using
this contrived example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cpp" data-lang="cpp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#5e81ac;font-style:italic">#include&lt;/span> &lt;span style="color:#5e81ac;font-style:italic">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span style="color:#5e81ac;font-style:italic">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#5e81ac;font-style:italic">#include&lt;/span> &lt;span style="color:#5e81ac;font-style:italic">&amp;lt;string&amp;gt;&lt;/span>&lt;span style="color:#5e81ac;font-style:italic">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#5e81ac;font-style:italic">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>std&lt;span style="color:#81a1c1">::&lt;/span>string foo&lt;span style="color:#eceff4">()&lt;/span> &lt;span style="color:#eceff4">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#81a1c1;font-weight:bold">return&lt;/span> &lt;span style="color:#a3be8c">&amp;#34;Hello, programmer!&amp;#34;&lt;/span>&lt;span style="color:#eceff4">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#eceff4">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#81a1c1">int&lt;/span> &lt;span style="color:#88c0d0">main&lt;/span>&lt;span style="color:#eceff4">()&lt;/span> &lt;span style="color:#eceff4">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> std&lt;span style="color:#81a1c1">::&lt;/span>string_view bar &lt;span style="color:#81a1c1">=&lt;/span> &lt;span style="color:#eceff4">{&lt;/span>foo&lt;span style="color:#eceff4">()};&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> std&lt;span style="color:#81a1c1">::&lt;/span>cout &lt;span style="color:#81a1c1">&amp;lt;&amp;lt;&lt;/span> bar &lt;span style="color:#81a1c1">&amp;lt;&amp;lt;&lt;/span> std&lt;span style="color:#81a1c1">::&lt;/span>endl&lt;span style="color:#eceff4">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#81a1c1;font-weight:bold">return&lt;/span> &lt;span style="color:#b48ead">0&lt;/span>&lt;span style="color:#eceff4">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#eceff4">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>A seasoned C++ programmer will immediately spot the problem, but someone who have only used a
memory-safe language like Java or Python before will be baffled why a seemingly trivial program
above may or may not print the string &lt;code>&amp;quot;Hello, programmer!\n&amp;quot;&lt;/code> depending on the chosen level of
optimizations, the version of a compiler, operating system, etc.&lt;/p></description></item><item><title>Debugging CPython processes with gdb</title><link>https://www.podoliaka.org/2016/04/10/debugging-cpython-gdb/</link><pubDate>Sun, 10 Apr 2016 00:00:00 +0000</pubDate><guid>https://www.podoliaka.org/2016/04/10/debugging-cpython-gdb/</guid><description>&lt;p>&lt;a href="https://docs.python.org/3.5/library/pdb.html" class="external-link" target="_blank" rel="noopener">pdb&lt;/a> has been, is and probably always will be the bread and butter of Python
programmers when they need to find the root cause of a problem in their
applications — it&amp;rsquo;s a built-in and easy to use debugger. But there are cases
when pdb can&amp;rsquo;t help you, e.g. if your app is stuck somewhere, and you
want to attach to a running process to find out why, without restarting it.
This is where &lt;a href="https://www.gnu.org/software/gdb/" class="external-link" target="_blank" rel="noopener">gdb&lt;/a> shines.&lt;/p></description></item><item><title>The story of one subtle optimization</title><link>https://www.podoliaka.org/2013/02/24/stringconcat-en/</link><pubDate>Sun, 24 Feb 2013 00:00:00 +0000</pubDate><guid>https://www.podoliaka.org/2013/02/24/stringconcat-en/</guid><description>&lt;p>In my previous job I worked on a web-service that was passing JSON payloads between workers using the
&lt;a href="http://gearman.org" class="external-link" target="_blank" rel="noopener">Gearman&lt;/a> task queue. One day I was trying to figure out why it took such a long
time (a few seconds) to transfer a 3-megabyte JSON value. I was sure that it was a problem in our code.
To my surprise, the profiler showed that the bottleneck was in this function of
&lt;a href="https://github.com/Yelp/python-gearman/" class="external-link" target="_blank" rel="noopener">python-gearman&lt;/a> client library:&lt;/p></description></item><item><title>Iterators for Beginners. The Way of С++</title><link>https://www.podoliaka.org/2013/01/20/iterators-en/</link><pubDate>Sun, 20 Jan 2013 00:00:00 +0000</pubDate><guid>https://www.podoliaka.org/2013/01/20/iterators-en/</guid><description>&lt;p>This post is mainly for beginners and is not intended to teach you everything
about iterators in C++. So if you know about &lt;code>iterator_traits&amp;lt;&amp;gt;&lt;/code> or advanced concepts
like that, you will not learn anything new. Anyway, I hope this information will be
useful for people who haven&amp;rsquo;t used C++ iterators before.&lt;/p>
&lt;h2 id="the-problem">
 The problem
 &lt;a class="heading-link" href="#the-problem">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h2>
&lt;p>Lets consider the following example: we need a function that would return an index of
the maximum element in a given array of integers. We could implement it like this:&lt;/p></description></item><item><title/><link>https://www.podoliaka.org/about/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.podoliaka.org/about/</guid><description>&lt;h1 id="about-me">
 About me
 &lt;a class="heading-link" href="#about-me">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h1>
&lt;p>Hey! I&amp;rsquo;m Roman, a software engineer from Ukraine who currently lives in Ireland.&lt;/p>
&lt;p>My programming language of choice is Python, as it allows me to be efficient and easily
express my thoughts. I used to do some C / C++ / Java programming in the past and keep using
those languages, but usually only when I need to read or modify someone else&amp;rsquo;s code.
I&amp;rsquo;m also a big fan of Rust and Clojure and use them occasionally for various pet projects.&lt;/p></description></item><item><title/><link>https://www.podoliaka.org/talks/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.podoliaka.org/talks/</guid><description>&lt;h1 id="talks">
 Talks
 &lt;a class="heading-link" href="#talks">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h1>
&lt;h2 id="2018">
 2018
 &lt;a class="heading-link" href="#2018">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h2>
&lt;ul>
&lt;li>&lt;em>Continuous Integration&lt;/em>: &lt;a href="openstackci/slides.pdf" >slides&lt;/a>, &lt;a href="https://www.youtube.com/watch?v=25cQ910pyGM" class="external-link" target="_blank" rel="noopener">video&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="2017">
 2017
 &lt;a class="heading-link" href="#2017">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h2>
&lt;ul>
&lt;li>&lt;em>Machine Learning 101&lt;/em> at &lt;a href="http://kharkivpy.org.ua/" class="external-link" target="_blank" rel="noopener">KharkivPy&lt;/a> #17: &lt;a href="https://www.youtube.com/watch?v=RtgpPMZu_TY" class="external-link" target="_blank" rel="noopener">video&lt;/a>, &lt;a href="http://nbviewer.jupyter.org/format/slides/github/malor/machine-learning-101/blob/master/index.ipynb#/" class="external-link" target="_blank" rel="noopener">slides&lt;/a>, &lt;a href="https://github.com/malor/machine-learning-101" class="external-link" target="_blank" rel="noopener">code&lt;/a>&lt;/li>
&lt;/ul>
&lt;ul>
&lt;li>&lt;em>Debugging CPython processes with gdb&lt;/em> at &lt;a href="http://kharkivpy.org.ua/" class="external-link" target="_blank" rel="noopener">KharkivPy&lt;/a> #15: &lt;a href="https://www.youtube.com/watch?v=3h4-XTYQhWc" class="external-link" target="_blank" rel="noopener">video&lt;/a>, &lt;a href="http://www.slideshare.net/amd4ever/debugging-of-cpython-applications-71486119" class="external-link" target="_blank" rel="noopener">slides&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="2016">
 2016
 &lt;a class="heading-link" href="#2016">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h2>
&lt;ul>
&lt;li>&lt;em>Switching to the new EngineFacade&lt;/em>: &lt;a href="http://www.slideshare.net/amd4ever/switching-to-the-new-enginefacade" class="external-link" target="_blank" rel="noopener">slides&lt;/a>&lt;/li>
&lt;/ul>
&lt;ul>
&lt;li>&lt;em>Debugging CPython processes with gdb&lt;/em> at &lt;a href="https://pl.pycon.org/" class="external-link" target="_blank" rel="noopener">PyCon PL&lt;/a> 2016: &lt;a href="http://www.slideshare.net/amd4ever/slides-67126020" class="external-link" target="_blank" rel="noopener">slides&lt;/a>, &lt;a href="https://www.youtube.com/watch?v=VIhT_XzWnl0" class="external-link" target="_blank" rel="noopener">video&lt;/a>&lt;/li>
&lt;/ul>
&lt;ul>
&lt;li>&lt;em>Python automated testing 101&lt;/em>: &lt;a href="autotesting/slides.pdf" >slides&lt;/a>&lt;/li>
&lt;/ul>
&lt;ul>
&lt;li>&lt;em>CPU profiling of Python applications&lt;/em> at &lt;a href="http://ua.pycon.org/" class="external-link" target="_blank" rel="noopener">PyCon UA&lt;/a> 2016: &lt;a href="https://www.youtube.com/watch?v=nW3nN7mbdG0" class="external-link" target="_blank" rel="noopener">video&lt;/a>, &lt;a href="profiling/slides.pdf" >slides&lt;/a>&lt;/li>
&lt;/ul>
&lt;ul>
&lt;li>&lt;em>CPU profiling of Python applications&lt;/em> at &lt;a href="http://kharkivpy.org.ua/" class="external-link" target="_blank" rel="noopener">KharkivPy&lt;/a> #12 (Kharkiv, Ukraine): &lt;a href="https://www.youtube.com/watch?v=KcvsJ1jvirA" class="external-link" target="_blank" rel="noopener">video&lt;/a>, &lt;a href="https://www.dropbox.com/s/8wdev9or47pdnq7/kharkivpy-profiling.tar.gz?dl=1" class="external-link" target="_blank" rel="noopener">slides&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="2015">
 2015
 &lt;a class="heading-link" href="#2015">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h2>
&lt;ul>
&lt;li>&lt;em>Debugging (C)Python applications&lt;/em> at &lt;a href="http://kharkivpy.org.ua/" class="external-link" target="_blank" rel="noopener">KharkivPy&lt;/a> #11 (Kharkiv, Ukraine): &lt;a href="https://www.youtube.com/watch?v=Yi1VuXjWV2E" class="external-link" target="_blank" rel="noopener">video&lt;/a>, &lt;a href="https://www.dropbox.com/s/bjowr0j4vck6ijy/kharkivpy-debugging.pdf?dl=1" class="external-link" target="_blank" rel="noopener">slides&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title/><link>https://www.podoliaka.org/talks/enginefacade/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.podoliaka.org/talks/enginefacade/</guid><description>&lt;h1 id="switching-to-the-new-enginefacade">
 Switching to the new EngineFacade
 &lt;a class="heading-link" href="#switching-to-the-new-enginefacade">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h1>
&lt;p>by Roman Podoliaka&lt;/p>
&lt;p>@rpodoliaka
irc: &lt;strong>rpodolyaka&lt;/strong>
&lt;a href="mailto:rpodolyaka@mirantis.com" >rpodolyaka@mirantis.com&lt;/a>&lt;/p>
&lt;p>slides: &lt;a href="http://podoliaka.org/talks/" class="external-link" target="_blank" rel="noopener">http://podoliaka.org/talks/&lt;/a>&lt;/p>
&lt;hr>
&lt;h1 id="the-new-enginefacade">
 The new EngineFacade
 &lt;a class="heading-link" href="#the-new-enginefacade">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h1>
&lt;ul>
&lt;li>spec: &lt;a href="https://specs.openstack.org/openstack/oslo-specs/specs/kilo/make-enginefacade-a-facade.html" class="external-link" target="_blank" rel="noopener">https://specs.openstack.org/openstack/oslo-specs/specs/kilo/make-enginefacade-a-facade.html&lt;/a>&lt;/li>
&lt;li>implemented by &lt;strong>zzzeek&lt;/strong> (Mike Bayer) in Liberty (oslo.db &amp;gt;= 1.12.0)&lt;/li>
&lt;li>a new clean API for using of oslo.db
&lt;ul>
&lt;li>thread-safe initialization&lt;/li>
&lt;li>declarative management of session / connection scope&lt;/li>
&lt;li>easier offloading of read-only transactions to asynchronous replicas&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3 id="old-enginefacade-thread-safe-initialization-is-left-up-to-users">
 &amp;ldquo;old&amp;rdquo; EngineFacade: thread-safe initialization is left up to users
 &lt;a class="heading-link" href="#old-enginefacade-thread-safe-initialization-is-left-up-to-users">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span>_ENGINE_FACADE &lt;span style="color:#81a1c1">=&lt;/span> &lt;span style="color:#81a1c1;font-weight:bold">None&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>_LOCK &lt;span style="color:#81a1c1">=&lt;/span> threading&lt;span style="color:#81a1c1">.&lt;/span>Lock&lt;span style="color:#eceff4">()&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#81a1c1;font-weight:bold">def&lt;/span> &lt;span style="color:#88c0d0">_create_facade_lazily&lt;/span>&lt;span style="color:#eceff4">():&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#81a1c1;font-weight:bold">global&lt;/span> _LOCK&lt;span style="color:#eceff4">,&lt;/span> _ENGINE_FACADE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#81a1c1;font-weight:bold">if&lt;/span> _ENGINE_FACADE &lt;span style="color:#81a1c1;font-weight:bold">is&lt;/span> &lt;span style="color:#81a1c1;font-weight:bold">None&lt;/span>&lt;span style="color:#eceff4">:&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#81a1c1;font-weight:bold">with&lt;/span> _LOCK&lt;span style="color:#eceff4">:&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#81a1c1;font-weight:bold">if&lt;/span> _ENGINE_FACADE &lt;span style="color:#81a1c1;font-weight:bold">is&lt;/span> &lt;span style="color:#81a1c1;font-weight:bold">None&lt;/span>&lt;span style="color:#eceff4">:&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> _ENGINE_FACADE &lt;span style="color:#81a1c1">=&lt;/span> db_session&lt;span style="color:#81a1c1">.&lt;/span>EngineFacade&lt;span style="color:#81a1c1">.&lt;/span>from_config&lt;span style="color:#eceff4">(&lt;/span>CONF&lt;span style="color:#eceff4">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#81a1c1;font-weight:bold">return&lt;/span> _ENGINE_FACADE
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h3 id="new-enginefacade-lazy-thread-safe-initialization">
 &amp;ldquo;new&amp;rdquo; EngineFacade: lazy thread-safe initialization
 &lt;a class="heading-link" href="#new-enginefacade-lazy-thread-safe-initialization">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#81a1c1;font-weight:bold">from&lt;/span> &lt;span style="color:#8fbcbb">oslo.db&lt;/span> &lt;span style="color:#81a1c1;font-weight:bold">import&lt;/span> enginefacade &lt;span style="color:#81a1c1;font-weight:bold">as&lt;/span> sql
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#d08770">@sql.reader&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#81a1c1;font-weight:bold">def&lt;/span> &lt;span style="color:#88c0d0">some_api_method&lt;/span>&lt;span style="color:#eceff4">(&lt;/span>context&lt;span style="color:#eceff4">):&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#616e87;font-style:italic"># work with context.session&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#d08770">@sql.writer&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#81a1c1;font-weight:bold">def&lt;/span> &lt;span style="color:#88c0d0">some_other_api_method&lt;/span>&lt;span style="color:#eceff4">(&lt;/span>context&lt;span style="color:#eceff4">):&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#616e87;font-style:italic"># work with context.session&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h3 id="new-enginefacade-multiple-instances-of-enginefacade">
 &amp;ldquo;new&amp;rdquo; EngineFacade: multiple instances of EngineFacade
 &lt;a class="heading-link" href="#new-enginefacade-multiple-instances-of-enginefacade">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span>main_context_manager &lt;span style="color:#81a1c1">=&lt;/span> sql&lt;span style="color:#81a1c1">.&lt;/span>transaction_context&lt;span style="color:#eceff4">()&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>api_context_manager &lt;span style="color:#81a1c1">=&lt;/span> sql&lt;span style="color:#81a1c1">.&lt;/span>transaction_context&lt;span style="color:#eceff4">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h3 id="new-enginefacade-project-specific-configuration">
 &amp;ldquo;new&amp;rdquo; EngineFacade: project specific configuration
 &lt;a class="heading-link" href="#new-enginefacade-project-specific-configuration">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span>context_manager &lt;span style="color:#81a1c1">=&lt;/span> enginefacade&lt;span style="color:#81a1c1">.&lt;/span>transaction_context&lt;span style="color:#eceff4">()&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>context_manager&lt;span style="color:#81a1c1">.&lt;/span>configure&lt;span style="color:#eceff4">(&lt;/span>sqlite_fk&lt;span style="color:#81a1c1">=&lt;/span>&lt;span style="color:#81a1c1;font-weight:bold">True&lt;/span>&lt;span style="color:#eceff4">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>context_manager&lt;span style="color:#81a1c1">.&lt;/span>append_on_engine_create&lt;span style="color:#eceff4">(&lt;/span>set_hook&lt;span style="color:#eceff4">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h3 id="old-enginefacade-get_session-boilerplate">
 &amp;ldquo;old&amp;rdquo; EngineFacade: get_session() boilerplate
 &lt;a class="heading-link" href="#old-enginefacade-get_session-boilerplate">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#d08770">@require_context&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#d08770">@handle_db_data_error&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#81a1c1;font-weight:bold">def&lt;/span> &lt;span style="color:#88c0d0">snapshot_create&lt;/span>&lt;span style="color:#eceff4">(&lt;/span>context&lt;span style="color:#eceff4">,&lt;/span> values&lt;span style="color:#eceff4">):&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> values&lt;span style="color:#eceff4">[&lt;/span>&lt;span style="color:#a3be8c">&amp;#39;snapshot_metadata&amp;#39;&lt;/span>&lt;span style="color:#eceff4">]&lt;/span> &lt;span style="color:#81a1c1">=&lt;/span> \
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 	_metadata_refs&lt;span style="color:#eceff4">(&lt;/span>values&lt;span style="color:#81a1c1">.&lt;/span>get&lt;span style="color:#eceff4">(&lt;/span>&lt;span style="color:#a3be8c">&amp;#39;metadata&amp;#39;&lt;/span>&lt;span style="color:#eceff4">),&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> models&lt;span style="color:#81a1c1">.&lt;/span>SnapshotMetadata&lt;span style="color:#eceff4">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#81a1c1;font-weight:bold">if&lt;/span> &lt;span style="color:#81a1c1;font-weight:bold">not&lt;/span> values&lt;span style="color:#81a1c1">.&lt;/span>get&lt;span style="color:#eceff4">(&lt;/span>&lt;span style="color:#a3be8c">&amp;#39;id&amp;#39;&lt;/span>&lt;span style="color:#eceff4">):&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> values&lt;span style="color:#eceff4">[&lt;/span>&lt;span style="color:#a3be8c">&amp;#39;id&amp;#39;&lt;/span>&lt;span style="color:#eceff4">]&lt;/span> &lt;span style="color:#81a1c1">=&lt;/span> &lt;span style="color:#81a1c1">str&lt;/span>&lt;span style="color:#eceff4">(&lt;/span>uuid&lt;span style="color:#81a1c1">.&lt;/span>uuid4&lt;span style="color:#eceff4">())&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> session &lt;span style="color:#81a1c1">=&lt;/span> get_session&lt;span style="color:#eceff4">()&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#81a1c1;font-weight:bold">with&lt;/span> session&lt;span style="color:#81a1c1">.&lt;/span>begin&lt;span style="color:#eceff4">():&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> snapshot_ref &lt;span style="color:#81a1c1">=&lt;/span> models&lt;span style="color:#81a1c1">.&lt;/span>Snapshot&lt;span style="color:#eceff4">()&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> snapshot_ref&lt;span style="color:#81a1c1">.&lt;/span>update&lt;span style="color:#eceff4">(&lt;/span>values&lt;span style="color:#eceff4">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> session&lt;span style="color:#81a1c1">.&lt;/span>add&lt;span style="color:#eceff4">(&lt;/span>snapshot_ref&lt;span style="color:#eceff4">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#81a1c1;font-weight:bold">return&lt;/span> _snapshot_get&lt;span style="color:#eceff4">(&lt;/span>context&lt;span style="color:#eceff4">,&lt;/span> values&lt;span style="color:#eceff4">[&lt;/span>&lt;span style="color:#a3be8c">&amp;#39;id&amp;#39;&lt;/span>&lt;span style="color:#eceff4">],&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> session&lt;span style="color:#81a1c1">=&lt;/span>session&lt;span style="color:#eceff4">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h3 id="old-enginefacade-private-db-api-functions">
 &amp;ldquo;old&amp;rdquo; EngineFacade: private DB API functions
 &lt;a class="heading-link" href="#old-enginefacade-private-db-api-functions">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#d08770">@require_context&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#81a1c1;font-weight:bold">def&lt;/span> &lt;span style="color:#88c0d0">_snapshot_metadata_get&lt;/span>&lt;span style="color:#eceff4">(&lt;/span>context&lt;span style="color:#eceff4">,&lt;/span> snapshot_id&lt;span style="color:#eceff4">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> session&lt;span style="color:#81a1c1">=&lt;/span>&lt;span style="color:#81a1c1;font-weight:bold">None&lt;/span>&lt;span style="color:#eceff4">):&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> rows &lt;span style="color:#81a1c1">=&lt;/span> _snapshot_metadata_get_query&lt;span style="color:#eceff4">(&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 	context&lt;span style="color:#eceff4">,&lt;/span>snapshot_id&lt;span style="color:#eceff4">,&lt;/span> session&lt;span style="color:#eceff4">)&lt;/span>&lt;span style="color:#81a1c1">.&lt;/span>all&lt;span style="color:#eceff4">()&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> result &lt;span style="color:#81a1c1">=&lt;/span> &lt;span style="color:#eceff4">{}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#81a1c1;font-weight:bold">for&lt;/span> row &lt;span style="color:#81a1c1;font-weight:bold">in&lt;/span> rows&lt;span style="color:#eceff4">:&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> result&lt;span style="color:#eceff4">[&lt;/span>row&lt;span style="color:#eceff4">[&lt;/span>&lt;span style="color:#a3be8c">&amp;#39;key&amp;#39;&lt;/span>&lt;span style="color:#eceff4">]]&lt;/span> &lt;span style="color:#81a1c1">=&lt;/span> row&lt;span style="color:#eceff4">[&lt;/span>&lt;span style="color:#a3be8c">&amp;#39;value&amp;#39;&lt;/span>&lt;span style="color:#eceff4">]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#81a1c1;font-weight:bold">return&lt;/span> result
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h3 id="new-enginefacade-session-scope-is-managed-declaratively">
 &amp;ldquo;new&amp;rdquo; EngineFacade: session scope is managed declaratively
 &lt;a class="heading-link" href="#new-enginefacade-session-scope-is-managed-declaratively">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-python" data-lang="python">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#d08770">@main_context_manager.writer&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#81a1c1;font-weight:bold">def&lt;/span> &lt;span style="color:#88c0d0">quota_destroy_all_by_project_and_user&lt;/span>&lt;span style="color:#eceff4">(&lt;/span>context&lt;span style="color:#eceff4">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> project_id&lt;span style="color:#eceff4">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> user_id&lt;span style="color:#eceff4">):&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> model_query&lt;span style="color:#eceff4">(&lt;/span>context&lt;span style="color:#eceff4">,&lt;/span> models&lt;span style="color:#81a1c1">.&lt;/span>ProjectUserQuota&lt;span style="color:#eceff4">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> read_deleted&lt;span style="color:#81a1c1">=&lt;/span>&lt;span style="color:#a3be8c">&amp;#34;no&amp;#34;&lt;/span>&lt;span style="color:#eceff4">)&lt;/span>&lt;span style="color:#81a1c1">.&lt;/span>\
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> filter_by&lt;span style="color:#eceff4">(&lt;/span>project_id&lt;span style="color:#81a1c1">=&lt;/span>project_id&lt;span style="color:#eceff4">)&lt;/span>&lt;span style="color:#81a1c1">.&lt;/span>\
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> filter_by&lt;span style="color:#eceff4">(&lt;/span>user_id&lt;span style="color:#81a1c1">=&lt;/span>user_id&lt;span style="color:#eceff4">)&lt;/span>&lt;span style="color:#81a1c1">.&lt;/span>\
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> soft_delete&lt;span style="color:#eceff4">(&lt;/span>synchronize_session&lt;span style="color:#81a1c1">=&lt;/span>&lt;span style="color:#81a1c1;font-weight:bold">False&lt;/span>&lt;span style="color:#eceff4">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h1 id="what-projects-are-already-using-the-new-enginefacade">
 What projects are already using the new EngineFacade?
 &lt;a class="heading-link" href="#what-projects-are-already-using-the-new-enginefacade">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h1>
&lt;ul>
&lt;li>&lt;a href="https://review.openstack.org/#/q/status:merged&amp;#43;project:openstack/nova&amp;#43;branch:master&amp;#43;topic:bp/new-oslodb-enginefacade" class="external-link" target="_blank" rel="noopener">Nova&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://review.openstack.org/#/q/status:merged&amp;#43;project:openstack/neutron&amp;#43;branch:master&amp;#43;topic:bp/enginefacade-switch" class="external-link" target="_blank" rel="noopener">Neutron&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://review.openstack.org/#/q/status:merged&amp;#43;project:openstack/ironic&amp;#43;branch:master&amp;#43;topic:enginefacade" class="external-link" target="_blank" rel="noopener">Ironic&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://review.openstack.org/#/c/257458/" class="external-link" target="_blank" rel="noopener">Keystone&lt;/a>&lt;/li>
&lt;li>&amp;hellip;&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h1 id="need-help">
 Need help?
 &lt;a class="heading-link" href="#need-help">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h1>
&lt;p>Slides: &lt;a href="http://podoliaka.org/talks/" class="external-link" target="_blank" rel="noopener">http://podoliaka.org/talks/&lt;/a>&lt;/p></description></item><item><title/><link>https://www.podoliaka.org/talks/gdbdebugging/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.podoliaka.org/talks/gdbdebugging/</guid><description>&lt;h1 id="debugging-cpython-processes-with-gdb">
 Debugging CPython processes with gdb
 &lt;a class="heading-link" href="#debugging-cpython-processes-with-gdb">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h1>
&lt;p>PyCon PL
October 15th, 2016
Ossa, Poland&lt;/p>
&lt;p>by Roman Podoliaka, Development Manager at &lt;a href="http://mirantis.com/" class="external-link" target="_blank" rel="noopener">Mirantis&lt;/a>&lt;/p>
&lt;ul>
&lt;li>twitter: @rpodoliaka&lt;/li>
&lt;li>email: &lt;a href="mailto:roman.podoliaka@gmail.com" >roman.podoliaka@gmail.com&lt;/a>&lt;/li>
&lt;li>blog: &lt;a href="http://podoliaka.org" class="external-link" target="_blank" rel="noopener">http://podoliaka.org&lt;/a>&lt;/li>
&lt;li>slides: &lt;a href="http://podoliaka.org/talks/" class="external-link" target="_blank" rel="noopener">http://podoliaka.org/talks/&lt;/a>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h1 id="goals-of-this-talk">
 Goals of this talk
 &lt;a class="heading-link" href="#goals-of-this-talk">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h1>
&lt;ul>
&lt;li>
&lt;p>make gdb &lt;strong>&amp;ldquo;a known unknown&amp;rdquo;&lt;/strong>, so that you consider it as an option in the future&lt;/p>
&lt;/li>
&lt;li>
&lt;p>highlight the common gotchas&lt;/p>
&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h1 id="why-debugging">
 Why debugging?
 &lt;a class="heading-link" href="#why-debugging">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h1>
&lt;ul>
&lt;li>
&lt;p>working on a huge open source cloud platform - &lt;a href="https://www.openstack.org/" class="external-link" target="_blank" rel="noopener">OpenStack&lt;/a>&lt;/p></description></item></channel></rss>