<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
<title type="text">bjg.io</title>
<generator uri="https://github.com/jekyll/jekyll">Jekyll</generator>
<link rel="self" type="application/atom+xml" href="/feed.xml" />
<link rel="alternate" type="text/html" href="" />
<updated>2022-11-26T02:08:58+00:00</updated>
<id>/</id>
<author>
  <name>Brian Gianforcaro</name>
  <uri>/</uri>
  <email>b.gianfo@gmail.com</email>
</author>


<entry>
  <title type="html"><![CDATA[SerenityOS Office Hours (with friends!)]]></title>
  <link rel="alternate" type="text/html" href="/interview/serenity-office-hours/" />
  <id>/interview/serenity-office-hours</id>
  <published>2022-07-24T00:00:00+00:00</published>
  <updated>2022-07-24T00:00:00+00:00</updated>
  <author>
    <name>Brian Gianforcaro</name>
    <uri></uri>
    <email>b.gianfo@gmail.com</email>
  </author>
  <content type="html">&lt;p&gt;On June 24th, 2022 &lt;a href=&quot;https://twitter.com/awesomekling&quot;&gt;Andreas&lt;/a&gt; asked
&lt;a href=&quot;https://twitter.com/bertalan_d&quot;&gt;Dániel Bertalan&lt;/a&gt; and I to join him during his weekly office hours stream. 
It was great to talk with the community and answer questions!&lt;/p&gt;

&lt;h3 id=&quot;serenityos-office-hours-on-youtube&quot;&gt;SerenityOS Office Hours On YouTube:&lt;/h3&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube-nocookie.com/embed/dfobZPonzUg&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

  &lt;p&gt;&lt;a href=&quot;/interview/serenity-office-hours/&quot;&gt;SerenityOS Office Hours (with friends!)&lt;/a&gt; was originally published by Brian Gianforcaro at &lt;a href=&quot;&quot;&gt;bjg.io&lt;/a&gt; on July 24, 2022.&lt;/p&gt;</content>
</entry>


<entry>
  <title type="html"><![CDATA[SerenityOS Developer Interview: Me!]]></title>
  <link rel="alternate" type="text/html" href="/interview/serenity-interview/" />
  <id>/interview/serenity-interview</id>
  <published>2021-12-14T00:00:00+00:00</published>
  <updated>2021-12-14T00:00:00+00:00</updated>
  <author>
    <name>Brian Gianforcaro</name>
    <uri></uri>
    <email>b.gianfo@gmail.com</email>
  </author>
  <content type="html">&lt;p&gt;In November of 2021 Andreas Kling asked if he could interview me for &lt;a href=&quot;https://www.youtube.com/c/AndreasKling&quot;&gt;his youtube channel&lt;/a&gt;. 
He has a &lt;a href=&quot;https://www.youtube.com/playlist?list=PLMOpZvQB55bdDy0Lgn9fG2c7NEK_rkkkQ&quot;&gt;very entertaining series&lt;/a&gt;
where he interviews developers who contribute to the SerenityOS project.&lt;/p&gt;

&lt;p&gt;It was wonderful talking with Andreas, I really enjoyed the experience.
SerenityOS has been a significant part of my life over the past few years,
so it was nice to let the community know a little bit more about me.&lt;/p&gt;

&lt;h3 id=&quot;the-interview-on-youtube&quot;&gt;The Interview On YouTube:&lt;/h3&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube-nocookie.com/embed/J8ZoH6afmtA&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

  &lt;p&gt;&lt;a href=&quot;/interview/serenity-interview/&quot;&gt;SerenityOS Developer Interview: Me!&lt;/a&gt; was originally published by Brian Gianforcaro at &lt;a href=&quot;&quot;&gt;bjg.io&lt;/a&gt; on December 14, 2021.&lt;/p&gt;</content>
</entry>


<entry>
  <title type="html"><![CDATA[Mixed Extents 12: SQLPAL]]></title>
  <link rel="alternate" type="text/html" href="/podcast/mixed-extents/" />
  <id>/podcast/mixed-extents</id>
  <published>2021-11-19T00:00:00+00:00</published>
  <updated>2021-11-19T00:00:00+00:00</updated>
  <author>
    <name>Brian Gianforcaro</name>
    <uri></uri>
    <email>b.gianfo@gmail.com</email>
  </author>
  <content type="html">&lt;p&gt;Back in September of 2021 I was invited to talk about SQLPAL on the SQL Server
podcast &lt;a href=&quot;https://eightkb.online/mixedextents/&quot;&gt;Mixed Extents&lt;/a&gt;. The Mixed Extents
folks were a lot of fun to chat with. It’s always awesome getting to talk to a
group of passionate and informed power users of SQL Server On Linux!&lt;/p&gt;

&lt;h3 id=&quot;the-episode-on-youtube&quot;&gt;The Episode On YouTube:&lt;/h3&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube-nocookie.com/embed/NFTB1EIcR4s&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

  &lt;p&gt;&lt;a href=&quot;/podcast/mixed-extents/&quot;&gt;Mixed Extents 12: SQLPAL&lt;/a&gt; was originally published by Brian Gianforcaro at &lt;a href=&quot;&quot;&gt;bjg.io&lt;/a&gt; on November 19, 2021.&lt;/p&gt;</content>
</entry>


<entry>
  <title type="html"><![CDATA[Tricks for debugging python internals on Windows]]></title>
  <link rel="alternate" type="text/html" href="/debugging-python-in-windbg/" />
  <id>/debugging-python-in-windbg</id>
  <published>2020-08-09T00:00:00+00:00</published>
  <updated>2020-08-09T00:00:00+00:00</updated>
  <author>
    <name>Brian Gianforcaro</name>
    <uri></uri>
    <email>b.gianfo@gmail.com</email>
  </author>
  <content type="html">&lt;h2 id=&quot;background&quot;&gt;Background&lt;/h2&gt;

&lt;p&gt;At work I was debugging and issue where I had to dig into the internals
of the Python runtime running on Windows. Along the way I
learned a few tips and tricks that might come in handy for someone else. So I figured
I’d do a quick little write up to share the knowledge. To start
you’ll want to debug python with the windows system debugger: &lt;a href=&quot;https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/getting-started-with-windbg&quot;&gt;WinDbg&lt;/a&gt;.
Debugging runtime like Python is convenient in Visual Studio, but in the end it’s
not as powerful and features available in WinDbg will make things a lot easier.&lt;/p&gt;

&lt;h2 id=&quot;symbol-support&quot;&gt;Symbol Support&lt;/h2&gt;

&lt;p&gt;The first thing you’ll want is symbols for your python release.
There are multiple ways to get Python symbols:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;You can download them manually using this helpful &lt;a href=&quot;https://docs.microsoft.com/en-us/visualstudio/python/debugging-symbols-for-mixed-mode-c-cpp-python?view=vs-2019&quot;&gt;guide&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;You can use Sean Cline’s &lt;a href=&quot;https://github.com/SeanCline/PythonSymbols&quot;&gt;symbol server&lt;/a&gt;, and the debugger will download symbols for you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The symbol server support seems to work well, and is easy, so I would recommend that.
To add the symbol server to your WinDbg symbol path, run:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1:044&amp;gt; .sympath+ http://pythonsymbols.sdcline.com/symbols
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;source-support&quot;&gt;Source Support&lt;/h2&gt;

&lt;p&gt;Now that we have symbols, next we need to get the source to line up with the code you are
debugging and stepping through. First we need to use the debugger to find out what version
of python we are debugging:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1:044&amp;gt; !filever python38.dll
filever python38.dll
GetFileVersionInfo
Version: 3.8.150.1013 
0000000f`02ca0000 0000000f`030c9000   python38
    Loaded symbol image file: python38.dll
    Image path: python38.dll
    Image name: python38.dll
    Browse all global symbols  functions  data
    Timestamp:        Mon Oct 14 12:38:17 2019 (5DA4CEA9)
    CheckSum:         0040A466
    ImageSize:        00429000
    Product version:  3.8.150.1013
    File flags:       0 (Mask 3F)
    File OS:          4 Unknown Win32
    File type:        2.0 Dll
    File date:        00000000.00000000
    Translations:     0000.04b0
    Information from resource tables:
        CompanyName:      Python Software Foundation
        ProductName:      Python
        InternalName:     Python DLL
        OriginalFilename: python38.dll
        ProductVersion:   3.8.0
        FileVersion:      3.8.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The version I’m debugging appears to be based on Python 3.8.0, using that information
we can clone a copy of the cpython repository, and checkout the correct branch:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;c:\&amp;gt; git clone https://github.com/python/cpython.git
c:\&amp;gt; pushd cpython
c:\cpython&amp;gt; git tag -l | findstr 3.8.0
v3.8.0
...

c:\cpython&amp;gt; git checkout v3.8.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally we can fix up the source path in our debugger to point to our python source code:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1:044&amp;gt; .srcpath+ c:\cpython
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;dynamic-breakpoints&quot;&gt;Dynamic Breakpoints&lt;/h2&gt;

&lt;p&gt;Another trick that might need, is the ability to inject dynamic breakpoints into the python code
in order to narrow down a bug reproduction, or catch the system in a certain state.
Unfortunately there is no way to write inline assembly in python. However we can
take advantage of the Python &lt;a href=&quot;https://docs.python.org/3/library/ctypes.html&quot;&gt;ctypes library&lt;/a&gt;. It exposes the windll API with support for &lt;a href=&quot;https://en.wikipedia.org/wiki/Microsoft_Windows_library_files#KERNEL32.DLL&quot;&gt;kernel32.dll&lt;/a&gt;
exported functions. Using windll we can call into the windows implementation of &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/api/debugapi/nf-debugapi-debugbreak&quot;&gt;DebugBreak()&lt;/a&gt; via the foreign function wrapper.
This will trigger a breakpoint exception in the process, and the debugger will break into handle it.&lt;/p&gt;

&lt;p&gt;Here’s an example of using it to instrument some code:&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# Call DebugBreak export from kernel32
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ctypes&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;windll&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;windll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kernel32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DebugBreak&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;thing_you_are_trying_to_debug&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;the-pyext-windbg-extension&quot;&gt;The PyExt WinDbg Extension&lt;/h2&gt;

&lt;p&gt;Discovering the &lt;a href=&quot;https://github.com/SeanCline/PyExt&quot;&gt;PyExt&lt;/a&gt; WinDbg extension allowed
me to start being productive and narrowing down my issue.
It’s very useful for gleaning bits of information about the
python runtime while debugging and issue or analyzing a crash dump.&lt;/p&gt;

&lt;p&gt;To install, download the latest version from the PyExt &lt;a href=&quot;https://github.com/SeanCline/PyExt/releases&quot;&gt;Release Page&lt;/a&gt;.
Extract the zip file somewhere on disk.
Then you can load the extension into the debugger with the the following command.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;.load C:\PyExt-x64-Release\x64\Release\pyext.dll
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The extension exposes a few useful commands:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1:044&amp;gt; !pyext.help
Commands for C:\PyExt-x64-Release\x64\Release\pyext.dll:
  !help     - Displays information on available extension commands
  !pyobj    - Prints information about a Python object
  !pystack  - Prints the Python stack for the current thread, or starting at a
              provided PyFrameObject
  !pysymfix - Adds python symbols to the symbol path.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As a short cut to the steps listed above the extension provides a command to quickly
setup the python symbol server: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!pysymfix&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1:044&amp;gt; !pysymfix
Current symbol path: srv*
Adding symbol server to path...

************* Path validation summary **************
Response                         Time (ms)     Location
Deferred                                       http://pythonsymbols.sdcline.com/symbols
New symbol path: http://pythonsymbols.sdcline.com/symbols
Loading symbols...

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The extension also allows you to traverse the runtime stack frame object and display a
stack trace of the executing python code, using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!pystack&lt;/code&gt; command.
The utilize &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!pystack&lt;/code&gt; we’ll need to find a python stack frame pointer somewhere on on
the native call stack. Lets look around and try to find one:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1:044&amp;gt; .f+
06 0000000f`0044bfe0 0000000f`02ce9770 python38!_PyEval_EvalFrameDefault+0xaba

1:044&amp;gt; dv
prv param @r12  struct _frame * f = 0x0000000f`0886e800
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We simply pass the address of the _frame object to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!pystack&lt;/code&gt; command and let it work:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1:045&amp;gt; !pystack 0x0000000f0886e800 
Stack trace starting at (PyFrameObject*)(00000008`85b46130):
    File &quot;C:\python-3.8.0.amd64\lib\site-packages\pip\__main__.py&quot;, line 26, in &amp;lt;module&amp;gt;
                    [Locals] [Globals] 
    File &quot;C:\python-3.8.0.amd64\lib\runpy.py&quot;, line 85, in _run_code
                    [Globals] 
    File &quot;C:\python-3.8.0.amd64\lib\runpy.py&quot;, line 192, in _run_module_as_main
                    [Globals]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!pyobj&lt;/code&gt; extension allows you dump python runtime variables.
Objects in the CPython implementation are of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_object&lt;/code&gt;, this
is what &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!pyobj&lt;/code&gt; operates on.
Lets find an example in our test case, and try dumping it’s value:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1:049&amp;gt; g
Breakpoint 11 hit
python38!_io_FileIO___init___impl:
0000000f`02d3652c 48895c2410      mov     qword ptr [rsp+10h],rbx ss:0000000f`0044aff8=0000000000000002

1:049&amp;gt; dv nameobj
prv param  @rdx              @rdx              struct _object * nameobj = 0x0000000f`04cc2f10

1:049&amp;gt; !pyobj 0xf04cc2f10
PyASCIIObject at address: 0000000f`04cc2f10
    RefCount: 81
    Type: str
    Repr: 'C:\\python-3.8.0.amd64\\lib\\tempfile.py'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;These resources, tips, and tricks helped me dig into the problem I was working
on and figure out what was going on. I hope they might help out someone else out
there debugging python on windows. Thanks for reading!&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;/debugging-python-in-windbg/&quot;&gt;Tricks for debugging python internals on Windows&lt;/a&gt; was originally published by Brian Gianforcaro at &lt;a href=&quot;&quot;&gt;bjg.io&lt;/a&gt; on August 09, 2020.&lt;/p&gt;</content>
</entry>


<entry>
  <title type="html"><![CDATA[PR Dash: A command line pull request dashboard]]></title>
  <link rel="alternate" type="text/html" href="/pr-dash/" />
  <id>/pr-dash</id>
  <published>2020-07-03T00:00:00+00:00</published>
  <updated>2020-07-03T00:00:00+00:00</updated>
  <author>
    <name>Brian Gianforcaro</name>
    <uri></uri>
    <email>b.gianfo@gmail.com</email>
  </author>
  <content type="html">&lt;h3 id=&quot;many-code-review-systems&quot;&gt;Many Code Review Systems&lt;/h3&gt;

&lt;p&gt;I’m a strong believer in the value of &lt;a href=&quot;https://en.wikipedia.org/wiki/Code_review&quot;&gt;code review&lt;/a&gt;. I spend a large portion
of my days reviewing my peers’ code at my day job. At Microsoft the universal
tool for code review is &lt;a href=&quot;https://queue.acm.org/detail.cfm?id=3292420&quot;&gt;CodeFlow&lt;/a&gt;, a UI for reviewing code. It’s great at
showing you all of the details of a singular code review. &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/devops/repos/git/pull-requests?view=azure-devops&quot;&gt;Azure DevOps&lt;/a&gt;,
&lt;a href=&quot;https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/viewing-a-pull-request-review&quot;&gt;GitHub&lt;/a&gt;, and &lt;a href=&quot;https://about.gitlab.com/&quot;&gt;GitLab&lt;/a&gt; all have a way of viewing assigned reviews for given project.
Many developers today participate in projects across many different services;
some are involved in several internal projects during their work week and then
participate in or lead multiple open source projects in their free time.&lt;/p&gt;

&lt;p&gt;This whole system ends up being a bit of a time suck. All of these various platforms
rely on you to check them constantly to monitor progress on code reviews that you are
the author of, as well as reviews where you are a reviewer. This made me
wonder if it would be possible to create a grand, unified view of the status of
all your required work.&lt;/p&gt;

&lt;h3 id=&quot;jane-streets-iron&quot;&gt;Jane Street’s “Iron”&lt;/h3&gt;

&lt;p&gt;Years ago, I ran across the series of talks and blogs that the folks over at &lt;a href=&quot;https://www.janestreet.com&quot;&gt;Jane Street&lt;/a&gt;
put together about their internal code review system, Iron.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://blog.janestreet.com/code-review-that-isnt-boring/&quot;&gt;Code Review that isn’t boring&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://blog.janestreet.com/scrutinizing-your-code-in-style/&quot;&gt;Scrutinize your code in style&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://blog.janestreet.com/ironing-out-your-release-process/&quot;&gt;Iron out your release process&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://blog.janestreet.com/putting-the-i-back-in-ide-towards-a-github-explorer/&quot;&gt;Putting the I back in IDE: Towards a Github Explorer&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.janestreet.com/tech-talks/janestreet-code-review/&quot;&gt;How Jane Street Does Code Review&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube-nocookie.com/embed/MUqvXHEjmus&quot; frameborder=&quot;1&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;There are a ton of interesting things about the system they describe.
Including Iron ability to manage all review activities from a singular UI.
For instance, there is a global overview of all the reviews you are an author of
as well as, those you are a reviewer of. The overview gives you an idea
of how many lines are changed per review which allows you to quickly unblock
your peer by choosing to review their small pull requests before working on your
own projects.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blog.janestreet.com/putting-the-i-back-in-ide-towards-a-github-explorer/drilldown.gif&quot; alt=&quot;iron screenshot&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;introducing-pr-dash&quot;&gt;Introducing pr-dash&lt;/h3&gt;

&lt;p&gt;Late last year, I finally had enough of manually tracking pull requests across
the multiple repositories I contribute to every day. The faint memory of
the Iron user interface inspired me to create a tool for managing my pull requests.
I ended writing &lt;a href=&quot;https://github.com/bgianfo/pr-dash&quot;&gt;pr-dash&lt;/a&gt;, a console-based pull request dashboard.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/bgianfo/pr-dash/master/.assets/demo.png&quot; alt=&quot;pr-dash screenshot&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It’s currently written in C# using dotnet core, and &lt;a href=&quot;https://github.com/bgianfo/pr-dash&quot;&gt;lives on github&lt;/a&gt;.
Currently it is able abile to monitor Azure DevOps repositories, but it was built with
future extensibility in mind.&lt;/p&gt;

&lt;p&gt;The main features the tool offers are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Ability to filter only those PRs that are considered “actionable”, which filters PRs which you are waiting 
on feedback from the author, or have already signed off on, or are in draft state;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Ability to switch between actionable, signed off, draft, or PRs you are waiting on;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Ability to switch to just the PRs that you created and are waiting for feedback on.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you want to view a PR you can open it in your default web browser by pressing enter while
it’s selected. This allows you to take action on the pull request. The user interface refreshes
automatically in the background to make sure you are always up to date!&lt;/p&gt;

&lt;p&gt;It works well enough that I can use it for my work, and I have a few of my peers at work using
it as well. I’m eager to get more feedback and even contributions from the broader community.&lt;/p&gt;

&lt;p&gt;Feel free to get in touch with feedback on the projects issue tracker or reach out to me on Twitter!&lt;/p&gt;


  &lt;p&gt;&lt;a href=&quot;/pr-dash/&quot;&gt;PR Dash: A command line pull request dashboard&lt;/a&gt; was originally published by Brian Gianforcaro at &lt;a href=&quot;&quot;&gt;bjg.io&lt;/a&gt; on July 03, 2020.&lt;/p&gt;</content>
</entry>


<entry>
  <title type="html"><![CDATA[All Systems Go - 2019]]></title>
  <link rel="alternate" type="text/html" href="/conferences/all-systems-go-2019/" />
  <id>/conferences/all-systems-go-2019</id>
  <published>2019-10-07T00:00:00+00:00</published>
  <updated>2019-10-07T00:00:00+00:00</updated>
  <author>
    <name>Brian Gianforcaro</name>
    <uri></uri>
    <email>b.gianfo@gmail.com</email>
  </author>
  <content type="html">&lt;p&gt;Last month my colleagues &lt;a href=&quot;https://twitter.com/DBArgenis&quot;&gt;Argenis Fernandez&lt;/a&gt;, Eugene Birukov,
and I attended the &lt;a href=&quot;https://all-systems-go.io/&quot;&gt;All Systems Go! - 2019&lt;/a&gt; conference held from
September 20-22 in Berlin, Germany. &lt;strong&gt;All Systems Go!&lt;/strong&gt; is a conference
dedicated to Linux user space technologies. The audience appears to be a
mix of systems developers working on user space and kernel adjacent projects
from Facebook, RedHat, and various startups, to the consumers of these systems
in industry, and the community at large. 
The conference was dual track, with each talk clocking in at around 35 minutes on 
Friday and Saturday with a few lighting talks sprinkled throughout. Sunday was a
dedicated “Hackathon” for attendees to collaborate on whatever projects they want.&lt;/p&gt;

&lt;p&gt;&lt;img style=&quot;display:block; margin-top: 20px; margin-left: auto; margin-right: auto; height:45%; width:45%&quot; src=&quot;/images/all-systems-go-logo.svg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Microsoft was one of the conference sponsors, my team members and I attended
to give a talk about the unique technologies we used to ship SQL Server on
Linux, as well as evangelize Azure SQL Database Edge, running on ARM64.&lt;/p&gt;

&lt;p&gt;Links:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Conference website&lt;/strong&gt;: &lt;a href=&quot;https://all-systems-go.io/&quot;&gt;link&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Conference schedule&lt;/strong&gt;: &lt;a href=&quot;https://cfp.all-systems-go.io/ASG2019/schedule/&quot;&gt;link&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Recordings of all the conference talks&lt;/strong&gt;: &lt;a href=&quot;https://www.youtube.com/channel/UCeLpDT5afyiwdbbg1EOxOtQ/videos&quot;&gt;link&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;our-talk&quot;&gt;Our Talk:&lt;/h3&gt;

&lt;p&gt;Our talk seemed to be well received, although attendance did suffer with our
time slot being post lunch break and many people were still in line for the food trucks.
The audience had good questions during the QA, as well as after the talk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The slides are available on speaker deck:&lt;/strong&gt;&lt;/p&gt;
&lt;div style=&quot;left: 0; width: 100%; height: 0; position: relative; padding-bottom: 56.1972%;&quot;&gt;&lt;iframe src=&quot;//speakerdeck.com/player/9cdb72619d63468dbf4d6704c6f066a5&quot; style=&quot;border: 0; top: 0; left: 0; width: 100%; height: 100%; position: absolute;&quot; allowfullscreen=&quot;&quot; scrolling=&quot;no&quot; allow=&quot;encrypted-media&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The recording is available on YouTube:&lt;/strong&gt;&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube-nocookie.com/embed/zq1WTLnntIg&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;


  &lt;p&gt;&lt;a href=&quot;/conferences/all-systems-go-2019/&quot;&gt;All Systems Go - 2019&lt;/a&gt; was originally published by Brian Gianforcaro at &lt;a href=&quot;&quot;&gt;bjg.io&lt;/a&gt; on October 07, 2019.&lt;/p&gt;</content>
</entry>


<entry>
  <title type="html"><![CDATA[Mystery: HORIPAD switch controller not working with Steam on Linux?]]></title>
  <link rel="alternate" type="text/html" href="/guide/horipad-switch-linux/" />
  <id>/guide/horipad-switch-linux</id>
  <published>2019-01-13T00:00:00+00:00</published>
  <updated>2019-01-13T00:00:00+00:00</updated>
  <author>
    <name>Brian Gianforcaro</name>
    <uri></uri>
    <email>b.gianfo@gmail.com</email>
  </author>
  <content type="html">&lt;p&gt;I just picked up a &lt;a href=&quot;http://stores.horiusa.com/horipad-for-nintendo-switch/&quot;&gt;HORIPAD&lt;/a&gt; for the Switch.
Hoping I could use it with Steam on my Linux box in addition to the switch, I plugged it into my system running the 5.0-rc1 kernel.
It was a bit to my surprise, but it showed up as a recognized device:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-tcsh&quot; data-lang=&quot;tcsh&quot;&gt;$ dmesg
... snip ...
[    2.665567] input: HORI CO.,LTD. HORIPAD S as /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0/0003:0F0D:00C1.0001/input/input8
[    2.665671] hid-generic 0003:0F0D:00C1.0001: input,hidraw0: USB HID v1.11 Gamepad [HORI CO.,LTD. HORIPAD S] on usb-0000:00:14.0-1/input0&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We can find the same information in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lsusb&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-tcsh&quot; data-lang=&quot;tcsh&quot;&gt;$ lsusb -v 

Bus 001 Device 002: ID 0f0d:00c1 Hori Co., Ltd 
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x0f0d Hori Co., Ltd
  idProduct          0x00c1 
  bcdDevice            5.72
  iManufacturer           1 
  iProduct                2 
  iSerial                 0 
  bNumConfigurations      1

  ... snip ...&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So we know it’s recognized, lets see if &lt;a href=&quot;https://linux.die.net/man/1/jstest&quot;&gt;jstest&lt;/a&gt; can read input coming from the device:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-tcsh&quot; data-lang=&quot;tcsh&quot;&gt;$ jstest --normal /dev/input/js0

Driver version is 2.1.0.
Joystick (HORI CO.,LTD. HORIPAD S) has 6 axes (X, Y, Z, Rz, Hat0X, Hat0Y)
and 14 buttons (BtnA, BtnB, BtnC, BtnX, BtnY, BtnZ, BtnTL, BtnTR, BtnTL2, BtnTR2, BtnSelect, BtnStart, BtnMode, BtnThumbL).
Testing ... (interrupt to exit)
Axes:  0:     0  1:     0  2:     0  3:     0  4:     0  5:     0 Buttons:  0:off  1:off  2:off  3:off  4:off  5:off  6:off  7:off  8:off  9:off 10:off 11:off 12:off 13:off 
Axes:  0:     0  1:     0  2:     0  3:     0  4:     0  5:     0 Buttons:  0:off  1:on   2:off  3:off  4:off  5:off  6:off  7:off  8:off  9:off 10:off 11:off 12:off 13:off 
Axes:  0:     0  1:     0  2:     0  3:     0  4:     0  5:     0 Buttons:  0:off  1:on   2:off  3:off  4:off  5:off  6:off  7:off  8:off  9:off 10:off 11:off 12:off 13:off 
Axes:  0:     0  1:     0  2:     0  3:     0  4:     0  5:     0 Buttons:  0:off  1:off  2:on   3:off  4:off  5:off  6:off  7:off  8:off  9:off 10:off 11:off 12:off 13:off
Axes:  0:     0  1:     0  2:     0  3:     0  4:     0  5:     0 Buttons:  0:off  1:off  2:on   3:off  4:off  5:off  6:off  7:off  8:off  9:off 10:off 11:off 12:off 13:off
Axes:  0:  9458  1: -2703  2:     0  3:     0  4:     0  5:     0 Buttons:  0:off  1:off  2:off  3:off  4:off  5:off  6:off  7:off  8:off  9:off 10:off 11:off 12:off 13:off 
Axes:  0:-32767  1:     0  2:     0  3:     0  4:     0  5:     0 Buttons:  0:off  1:off  2:off  3:off  4:off  5:off  6:off  7:off  8:off  9:off 10:off 11:off 12:off 13:off
Axes:  0: -1014  1: 32767  2:-18580  3: 32767  4:     0  5:     0 Buttons:  0:off  1:off  2:off  3:off  4:off  5:off  6:off  7:off  8:off  9:off 10:off 11:off 12:off 13:off
Axes:  0: -1690  1: 32767  2:-18580  3: 32767  4:     0  5:     0 Buttons:  0:off  1:off  2:off  3:off  4:off  5:off  6:off  7:off  8:off  9:off 10:off 11:off 12:off 13:off
Axes:  0: -1690  1: 32767  2:-18580  3: 32767  4:     0  5:     0 Buttons:  0:off  1:off  2:off  3:off  4:off  5:off  6:off  7:off  8:off  9:off 10:off 11:off 12:off 13:off
Axes:  0: -2027  1: 32767  2:-18580  3: 32767  4:     0  5:     0 Buttons:  0:off  1:off  2:off  3:off  4:off  5:off  6:off  7:off  8:off  9:off 10:off 11:off 12:off 13:off
Axes:  0:     0  1:     0  2:     0  3:     0  4:     0  5:     0 Buttons:  0:off  1:off  2:off  3:off  4:off  5:off  6:off  7:off  8:off  9:off 10:off 11:off 12:off 13:off &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;All the buttons, sticks, and dpad seem to work and jstest is able to read signal from all inputs!
I opened up steam, thinking I was going to play &lt;a href=&quot;https://store.steampowered.com/app/504230/Celeste/&quot;&gt;Celeste&lt;/a&gt;. However steam reported that it didn’t recognize any controllers…
Going into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Settings -&amp;gt; Controllers -&amp;gt; General Controller Settings&lt;/code&gt;, I had the &lt;strong&gt;“Generic Gamepad Configuration Support”&lt;/strong&gt; option
&lt;strong&gt;checked&lt;/strong&gt;, as this wasn’t one of the known Xbox/PS/Switch controllers. Steam wasn’t able to see the device for some reason.&lt;/p&gt;

&lt;p&gt;After digging around online for a bit, I discovered the &lt;a href=&quot;https://github.com/ValveSoftware/steam-devices&quot;&gt;steam-devices&lt;/a&gt; package, which was recommended by
folks debugging other controllers. I installed that package, and nothing changed. :(&lt;/p&gt;

&lt;p&gt;Wondering what exactly this package does, I started to dig into what the package provided.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-tcsh&quot; data-lang=&quot;tcsh&quot;&gt;$ dpkg -L steam-devices

/.
/lib
/lib/udev
/lib/udev/rules.d
/lib/udev/rules.d/60-HTC-Vive-perms.rules
/lib/udev/rules.d/99-steam-controller-perms.rules
/usr
/usr/share
/usr/share/doc
/usr/share/doc/steam-devices
/usr/share/doc/steam-devices/changelog.Debian.gz
/usr/share/doc/steam-devices/copyright&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;That &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;99-steam-controller-perm.rules&lt;/code&gt; file stood out as interesting.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-tcsh&quot; data-lang=&quot;tcsh&quot;&gt;$ head /lib/udev/rules.d/99-steam-controller-perms.rules

# Valve USB devices
SUBSYSTEM==&quot;usb&quot;, ATTRS{idVendor}==&quot;28de&quot;, MODE=&quot;0666&quot;
# Steam Controller udev write access
KERNEL==&quot;uinput&quot;, SUBSYSTEM==&quot;misc&quot;, TAG+=&quot;uaccess&quot;

# Valve HID devices over USB hidraw
KERNEL==&quot;hidraw*&quot;, ATTRS{idVendor}==&quot;28de&quot;, MODE=&quot;0666&quot;

# Valve HID devices over bluetooth hidraw
KERNEL==&quot;hidraw*&quot;, KERNELS==&quot;*28DE:*&quot;, MODE=&quot;0666&quot;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;It looks like a bunch of &lt;a href=&quot;https://mirrors.edge.kernel.org/pub/linux/utils/kernel/hotplug/udev/udev.html&quot;&gt;udev rules&lt;/a&gt; for configuring the permission for hidraw and uinput devices.
We saw in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dmesg&lt;/code&gt; output above that our controller is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hidraw&lt;/code&gt; device, maybe we need to setup
permissions for the device to be read by non elevated users?&lt;/p&gt;

&lt;p&gt;To test this out I appended the following to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;99-steam-controller-perm.rules&lt;/code&gt; file.
I found the vendor id and product id for the HORIPAD using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lsusb -v&lt;/code&gt; (as seen above).&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-perl&quot; data-lang=&quot;perl&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# HORIPAD S over USB hidraw&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;KERNEL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;hidraw*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&quot;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ATTRS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;idVendor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;0f0d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&quot;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ATTRS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;idProduct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;00c1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&quot;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;MODE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;0666&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Not wanting to reboot I quickly dug up &lt;a href=&quot;https://unix.stackexchange.com/questions/39370/how-to-reload-udev-rules-without-reboot&quot;&gt;how to force reload udev rules&lt;/a&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-tcsh&quot; data-lang=&quot;tcsh&quot;&gt;$ sudo udevadm control --reload-rules 
$ sudo udevadm trigger&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;A few seconds later, steam popped up a window informing me that it had recognized a new controller!&lt;/p&gt;

&lt;p&gt;I started up &lt;a href=&quot;https://store.steampowered.com/app/504230/Celeste/&quot;&gt;Celeste&lt;/a&gt; and everything worked like a charm.
Off to play the game!&lt;/p&gt;


  &lt;p&gt;&lt;a href=&quot;/guide/horipad-switch-linux/&quot;&gt;Mystery: HORIPAD switch controller not working with Steam on Linux?&lt;/a&gt; was originally published by Brian Gianforcaro at &lt;a href=&quot;&quot;&gt;bjg.io&lt;/a&gt; on January 13, 2019.&lt;/p&gt;</content>
</entry>


<entry>
  <title type="html"><![CDATA[Link: C++ Interlude 2015]]></title>
  <link rel="alternate" type="text/html" href="/cpp-interlude-2015/" />
  <id>/cpp-interlude-2015</id>
  <published>2016-01-02T00:00:00+00:00</published>
  <updated>2016-01-02T00:00:00+00:00</updated>
  <author>
    <name>Brian Gianforcaro</name>
    <uri></uri>
    <email>b.gianfo@gmail.com</email>
  </author>
  <content type="html">&lt;!-- Sources --&gt;

&lt;p&gt;&lt;strong&gt;Agustin Bergé&lt;/strong&gt; wrote up a great summary of the changes 2015 brought to the C++ language, and what might be coming in C++17.
The post is available &lt;a href=&quot;http://talesofcpp.fusionfenix.com/post-23/interlude&quot;&gt;&lt;strong&gt;here&lt;/strong&gt;&lt;/a&gt;, it’s well worth the read.&lt;/p&gt;

&lt;h3 id=&quot;just-a-quick-aside&quot;&gt;Just A Quick Aside:&lt;/h3&gt;
&lt;p&gt;Looking at the &lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/&quot;&gt;list&lt;/a&gt; of papers from the C++ Standards Committee in 2015,
one of the recent entries &lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0157r0.html&quot;&gt;P0155R0&lt;/a&gt; - “Handling Disappointment in C++”, peeked my interest a bit.
During the past few years I’ve always been very interested in error handling techniques besides the standard return status code, or exception based solutions. In Handling Disappointment in C++ Lawrence Crowl
compares two proposals &lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4109.pdf&quot;&gt;N4109&lt;/a&gt; - Addition of the Expected Monad and &lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4233.html&quot;&gt;N4233&lt;/a&gt; - A Class for Status and Optional Value.&lt;/p&gt;

&lt;p&gt;I need to take some time and play with the &lt;a href=&quot;https://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C&quot;&gt;Expected&amp;lt;T&amp;gt;&lt;/a&gt; style error handling and see how well it would fair in production code. Maybe in a future post?&lt;/p&gt;


  &lt;p&gt;&lt;a href=&quot;/cpp-interlude-2015/&quot;&gt;Link: C++ Interlude 2015&lt;/a&gt; was originally published by Brian Gianforcaro at &lt;a href=&quot;&quot;&gt;bjg.io&lt;/a&gt; on January 02, 2016.&lt;/p&gt;</content>
</entry>


<entry>
  <title type="html"><![CDATA[Mystery: Why is MSYS2 executing so slowly?]]></title>
  <link rel="alternate" type="text/html" href="/guide/cygwin-ad/" />
  <id>/guide/cygwin-ad</id>
  <published>2015-03-16T00:00:00+00:00</published>
  <updated>2015-03-16T00:00:00+00:00</updated>
  <author>
    <name>Brian Gianforcaro</name>
    <uri></uri>
    <email>b.gianfo@gmail.com</email>
  </author>
  <content type="html">&lt;p&gt;I’ve always enjoyed using *nix tools, even when working on a Windows machine.
In the past I had always used Cygwin, but recently I have been playing around with
the &lt;a href=&quot;https://howistart.org/posts/elixir/1&quot;&gt;MSYS2&lt;/a&gt; project, which is a down stream fork of the Cygwin project. It has a few
interesting features, one of the most impressive being a real package manager.&lt;/p&gt;

&lt;p&gt;Recently I got a new development machine, so I decided to try a pure MSYS2 setup to see how well it would work.
After installing MSYS2 I noticed two particularly strange behaviors:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;The first issue was that it took an excessive amount of time to start a MSYS2 shell, on the order of 30 seconds.
However once the shell was started everything was very snappy.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;I often put the MSYS2/Cygwin tools in my normal windows console path. They are normally quite useful during my normal development.
When executing any of the MSYS2 tools which perform file access (like ls, grep, etc) there was a significant delay during
execution. If you let the program continue to execute it would eventually finish, but it was obviously an unproductive work flow…&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Initially I didn’t connect the two issues together, as I was seeing them in two entirely separate usage patterns.
After digging around in the documentation for a while and coming up with nothing, I finally thought hey lets just use &lt;a href=&quot;http://en.wikipedia.org/wiki/Strace&quot;&gt;strace&lt;/a&gt;!
Strace immediately revealed the issue, there were thousands of references to a single function when ever a program which dealt with file access was executing.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-tcsh&quot; data-lang=&quot;tcsh&quot;&gt;$ strace ls
  ... snip ...
  497 5276872 [main] ls 9004 pwdgrp::fetch_account_from_windows: line: &amp;lt;xxxxxxxxxxxxxx1:&amp;gt;
  492 5277364 [main] ls 9004 pwdgrp::fetch_account_from_windows: line: &amp;lt;xxxxxxxxxxxxxx2:&amp;gt;
  520 5277884 [main] ls 9004 pwdgrp::fetch_account_from_windows: line: &amp;lt;xxxxxxxxxxxxxx3:&amp;gt;
  521 5278405 [main] ls 9004 pwdgrp::fetch_account_from_windows: line: &amp;lt;xxxxxxxxxxxxxx4:&amp;gt;
  495 5278900 [main] ls 9004 pwdgrp::fetch_account_from_windows: line: &amp;lt;xxxxxxxxxxxxxx5:&amp;gt;
  496 5279396 [main] ls 9004 pwdgrp::fetch_account_from_windows: line: &amp;lt;xxxxxxxxxxxxxx6:&amp;gt;
  493 5279889 [main] ls 9004 pwdgrp::fetch_account_from_windows: line: &amp;lt;xxxxxxxxxxxxxx7:&amp;gt;
  493 5280382 [main] ls 9004 pwdgrp::fetch_account_from_windows: line: &amp;lt;xxxxxxxxxxxxxx8:&amp;gt;
  497 5280879 [main] ls 9004 pwdgrp::fetch_account_from_windows: line: &amp;lt;xxxxxxxxxxxxxx9:&amp;gt;
  ... snip ...&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;catching-a-lead&quot;&gt;Catching A Lead&lt;/h3&gt;

&lt;p&gt;Armed with the actual function call which was wreaking havoc, I hit up Google.
I eventually ran across &lt;a href=&quot;https://www.cygwin.com/ml/cygwin/2015-02/msg00386.html&quot;&gt;this news group post&lt;/a&gt;, where Michael Klemm seemed to be having similar problems as
I was. Reading through the mail, Andrey Repin points to a &lt;a href=&quot;https://cygwin.com/faq/faq.html#faq.using.startup-slow&quot;&gt;FAQ entry&lt;/a&gt; which describes in detail the exact issue I was hitting:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Starting a new terminal window is slow. What’s going on?&lt;/p&gt;

  &lt;p&gt;There are many possible causes for this.&lt;/p&gt;

  &lt;p&gt;If your terminal windows suddenly began starting slowly after a Cygwin upgrade, it may indicate issues in the authentication setup.&lt;/p&gt;

  &lt;p&gt;For almost all its lifetime, Cygwin has used Unix-like /etc/passwd and /etc/group files to mirror the contents of the Windows SAM and AD databases. Although these files can still be used, since Cygwin 1.7.34, new installations now use the SAM/AD databases directly.&lt;/p&gt;

  &lt;p&gt;To switch to the new method, move these two files out of the way and restart the Cygwin terminal. That runs Cygwin in its new default mode.
If you are on a system that isn’t using AD domain logins, this makes Cygwin use the native Windows SAM database directly, which may be faster than the old method involving /etc/passwd and such. At worst, it will only be a bit slower. (The speed difference you see depends on which benchmark you run.) For the AD case, it can be slower than the old method, since it is trading a local file read for a network request. Version 1.7.35 will reduce the number of AD server requests the DLL makes relative to 1.7.34, with the consequence that you will now have to alter /etc/nsswitch.conf in order to change your Cygwin home directory, instead of being able to change it from the AD configuration.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This explains the issue I was experiencing, my machine was joined to a very large AD deployment.
The Cygwin/MSYS2 runtime was attempting to enumerate the thousands of users and groups as part of
the process of loading the shell process initially, resulting in slow terminal start up.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The Cygwin DLL queries information about every group you’re in to populate the local cache on startup.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The fact that this is an in memory cache, populated on the load of runtime dll explains the second symptom.
When not running under the Cygwin/MSYS2 shell, the runtime dll isn’t going to be already loaded and used by the utilities
so every invocation of tools like &lt;strong&gt;ls&lt;/strong&gt; or &lt;strong&gt;grep&lt;/strong&gt; results in a separate load of the runtime and as a result an enumeration of the AD groups.&lt;/p&gt;

&lt;h3 id=&quot;solution&quot;&gt;Solution&lt;/h3&gt;

&lt;p&gt;If you continue reading the FAQ, the steps necessary to cache your users and group memberships is listed.
However given my previously discussed situation of being part of a very large AD deployment I only wanted 
to include my current user info as well as my current users groups to avoid a huge cache (see a &lt;a href=&quot;https://www.cygwin.com/ml/cygwin/2008-03/msg00162.html&quot;&gt;related mail thread&lt;/a&gt;).
To achieve this I did the following:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-tcsh&quot; data-lang=&quot;tcsh&quot;&gt;$ mkpasswd -l -c &amp;gt; /etc/passwd
$ mkgroup -l -c &amp;gt; /etc/group&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Once we have the local cache populated, we can configure Cygwin/MSYS2 to read from the files, instead of querying AD.
This is achieved by editing &lt;strong&gt;/etc/nsswitch.conf&lt;/strong&gt; and modifying &lt;strong&gt;passwd&lt;/strong&gt; and &lt;strong&gt;group&lt;/strong&gt; sections to read from &lt;strong&gt;“files”&lt;/strong&gt; instead of &lt;strong&gt;“files db”&lt;/strong&gt;, on lines 2 and 3 below:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-properties&quot; data-lang=&quot;properties&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# Begin /etc/nsswitch.conf
&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;passwd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;files&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;files&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;db_enum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;cache builtin&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;db_home&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;cygwin desc&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;db_shell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;cygwin desc&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;db_gecos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;cygwin desc&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;/etc/nsswitch.conf&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Once you restart you Cygwin/MSYS2 console, the change should take effect immediately.&lt;/p&gt;


  &lt;p&gt;&lt;a href=&quot;/guide/cygwin-ad/&quot;&gt;Mystery: Why is MSYS2 executing so slowly?&lt;/a&gt; was originally published by Brian Gianforcaro at &lt;a href=&quot;&quot;&gt;bjg.io&lt;/a&gt; on March 16, 2015.&lt;/p&gt;</content>
</entry>


<entry>
  <title type="html"><![CDATA[Presentation: Papers We Love - Managing Update Conflicts in Bayou]]></title>
  <link rel="alternate" type="text/html" href="/distributed-systems/bayou/" />
  <id>/distributed-systems/bayou</id>
  <published>2015-03-15T00:00:00+00:00</published>
  <updated>2015-03-15T00:00:00+00:00</updated>
  <author>
    <name>Brian Gianforcaro</name>
    <uri></uri>
    <email>b.gianfo@gmail.com</email>
  </author>
  <content type="html">&lt;iframe width=&quot;1280&quot; height=&quot;750&quot; src=&quot;https://www.youtube.com/embed/tg7zvyWm_NE&quot; frameborder=&quot;10&quot; allowfullscreen=&quot;&quot;&gt;
&lt;/iframe&gt;

&lt;p&gt;&lt;em&gt;Description From the video:&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Peter Bailis presents the “Managing Update Conflicts in Bayou, A Weakly Connected Replicated Storage System” paper by Doug Terry, Marvin Theimer, Karin Petersen, Alan J. Demers, Mike J. Spreitzer, and Carl H. Hauser in SOSP 1995.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Peter does wonderful job summarizing the paper, and discussing the design implications of the project in relation to modern day systems.
You can find the original paper &lt;a href=&quot;http://db.cs.berkeley.edu/cs286/papers/bayou-sosp1995.pdf&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;/distributed-systems/bayou/&quot;&gt;Presentation: Papers We Love - Managing Update Conflicts in Bayou&lt;/a&gt; was originally published by Brian Gianforcaro at &lt;a href=&quot;&quot;&gt;bjg.io&lt;/a&gt; on March 15, 2015.&lt;/p&gt;</content>
</entry>


<entry>
  <title type="html"><![CDATA[Learning Elixir]]></title>
  <link rel="alternate" type="text/html" href="/learning-elixir/" />
  <id>/learning-elixir</id>
  <published>2014-11-30T00:00:00+00:00</published>
  <updated>2014-11-30T00:00:00+00:00</updated>
  <author>
    <name>Brian Gianforcaro</name>
    <uri></uri>
    <email>b.gianfo@gmail.com</email>
  </author>
  <content type="html">&lt;!-- The Sources --&gt;

&lt;h2 id=&quot;intro&quot;&gt;Intro&lt;/h2&gt;
&lt;p&gt;Elixir has been on my radar for about a year now, however despite my best effort I haven’t had a chance to take a thorough look yet.
I decided I’ve been waiting long enough, I just need to sit down and try to hack out some code.
If you haven’t looked into the language yet it appears &lt;a href=&quot;https://en.wikipedia.org/wiki/Elixir_(programming_language)&quot;&gt;very cool on paper&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Elixir is a functional, concurrent, general-purpose programming language built atop the
&lt;a href=&quot;http://www.erlang.org/faq/implementations.html#idp32748048&quot;&gt;Erlang Virtual Machine&lt;/a&gt; (BEAM). Elixir builds on top of Erlang to provide distributed,
fault-tolerant, soft real-time, non-stop applications but also extends it to support 
metaprogramming with macros and polymorphism via protocols.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Installation was super easy, just head over to the &lt;a href=&quot;http://elixir-lang.org/install.htm-lang.org&quot;&gt;install&lt;/a&gt; page on &lt;a href=&quot;http://elixir-lang.org&quot;&gt;http://elixir-lang.org&lt;/a&gt;.
The windows web installer will download and install everything you need, a totally seamless experience.&lt;/p&gt;

&lt;p&gt;I have a little bit of familiarity with Erlang, but besides that this is the first time
I’ve actually looked into the Elixir syntax. So the rest of this post will be entirely,
unfiltered stream of consciousness.&lt;/p&gt;

&lt;h2 id=&quot;trying-out-some-code&quot;&gt;Trying Out Some Code&lt;/h2&gt;
&lt;p&gt;Lets see if we can use Elixir to solve the first problem on the &lt;a href=&quot;https://projecteuler.net&quot;&gt;Project Euler&lt;/a&gt; site.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Multiples of 3 and 5&lt;/strong&gt;:
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First lets try to fire up the REPL, I think I remember front page mentioning it was called &lt;strong&gt;iex&lt;/strong&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-tcsh&quot; data-lang=&quot;tcsh&quot;&gt;$ iex
Interactive Elixir (1.0.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Great, so lets try to start working on the problem.
Seems like we can naively solve this by traversing a list,
lets see if we can figure out the syntax for that.
Maybe it’s like Haskell? [1..10.]&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-tcsh&quot; data-lang=&quot;tcsh&quot;&gt;iex(1)&amp;gt; [1...1000]
** (SyntaxError) iex:2: syntax error before: '...'&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Hrmm… that didn’t work.
Maybe lets try dropping the brackets?
I think i vaguely remember Erlang only using two dots in the notation?&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-tcsh&quot; data-lang=&quot;tcsh&quot;&gt;iex(1)&amp;gt; 1 .. 1000
1..1000&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;That looks like it could be a representation of a list!
I wonder how we could take the head it?&lt;/p&gt;

&lt;p&gt;Lets try just a function?&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-tcsh&quot; data-lang=&quot;tcsh&quot;&gt;iex(2)&amp;gt; head(1 .. 1000)
** (RuntimeError) undefined function: head/1&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Maybe it’s prolog/erlang style, using the symbolic syntax?&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-tcsh&quot; data-lang=&quot;tcsh&quot;&gt;iex(3)&amp;gt; x = 1 .. 1000
1..1000
iex(4)&amp;gt; x
1..1000
iex(5)&amp;gt; [y|z] = x
** (MatchError) no match of right hand side value: 1..1000&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Looks like that’s not right… something seems off I thought that would work…
It seems like the language is probably erlang with some syntax.
I vaguely remember the head function in erlang being hd/1,
let’s try that on our list.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-tcsh&quot; data-lang=&quot;tcsh&quot;&gt;iex(5)&amp;gt; hd
** (RuntimeError) undefined function: hd/0

iex(5)&amp;gt; hd(x)
** (ArgumentError) argument error
    :erlang.hd(1..1000)
iex(5)&amp;gt; [x]
[1..1000]

iex(6)&amp;gt; head([x])
** (RuntimeError) undefined function: head/1

iex(6)&amp;gt; hd([x])
1..1000

iex(7)&amp;gt; hd([1 .. 2])
1..2&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Hrm… it seems like the 1..1000 syntax doesn’t create a list, maybe it’s a symbol?
Time to go read the docs …&lt;/p&gt;

&lt;p&gt;So after reading the &lt;a href=&quot;http://elixir-lang.org/getting_started/2.html#2.6-(linked)-lists&quot;&gt;docs&lt;/a&gt; for lists it seems like, the
bracket syntax is correct. hd/1 is head as we thought and tl/1b is tail.
However they don’t seem to cover the range syntax on that page. Need to
dig in to the docs a little bit more I guess, maybe there is no range syntax?&lt;/p&gt;

&lt;p&gt;Ahha! It looks like on &lt;a href=&quot;http://elixir-lang.org/getting_started/10.html&quot;&gt;this page&lt;/a&gt; that we were actually kind of 
correct. 1..1000 seems to represent a lazy range, not a list. So we need to use functions
to operate on top of the lazy range.&lt;/p&gt;

&lt;p&gt;Looks like there is a Stream package for lazy sequences, which has map/filter:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-tcsh&quot; data-lang=&quot;tcsh&quot;&gt;iex(8)&amp;gt; 1..1000 |&amp;gt; Stream.filter
** (UndefinedFunctionError) undefined function: Stream.filter/1
    (elixir) Stream.filter(1..1000)&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Need to figure out how to write a lambda, lets try to filter out odd numbers..
one of the map examples in the docs page uses this syntax:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Seems to make sense, lets try it out.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-tcsh&quot; data-lang=&quot;tcsh&quot;&gt;iex(8)&amp;gt; 1..1000 |&amp;gt; Stream.filter(fn x -&amp;gt; rem(x,2 == 0) end)
** (ArithmeticError) bad argument in arithmetic expression
             :erlang.rem(1, false)
    (elixir) lib/enum.ex:666: anonymous fn/3 in Enum.filter/2
    (elixir) lib/range.ex:77: Enumerable.Range.reduce/6
    (elixir) lib/enum.ex:666: Enum.filter/2&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I would have thought that would have worked… wait the parenthesis don’t look right.
I forgot to properly close the rem(..)!&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-tcsh&quot; data-lang=&quot;tcsh&quot;&gt;iex(8)&amp;gt; 1..1000 |&amp;gt; Stream.filter(fn x -&amp;gt; rem(x,2) == 0 end)
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42,
 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82,
 84, 86, 88, 90, 92, 94, 96, 98, 100, ...]&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;cool.&lt;/p&gt;

&lt;p&gt;I think I saw a Enum.sum function as well, putting all the pieces of the question together
we get a nice one liner.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-tcsh&quot; data-lang=&quot;tcsh&quot;&gt;iex(12)&amp;gt; multiples = fn x -&amp;gt; rem(x,3) == 0 || rem(x,5) == 0 end
#Function&amp;lt;6.90072148/1 in :erl_eval.expr/5&amp;gt;
iex(13)&amp;gt; 1..999 |&amp;gt; Stream.filter(multiples) |&amp;gt; Enum.sum
&amp;lt;redacted-from-article&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;That wasn’t so bad, I like the pipelining syntax. It seems similar to the syntax used in ML based language, like F#/OCaml.&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;p&gt;If you are on board with Elixir and want to continue on your own Elixir journey there are a couple of really great resources
to continue exploring the language.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://howistart.org/posts/elixir/1&quot;&gt;How I Start: Elixir&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Elixir-Lang Getting Started &lt;a href=&quot;http://elixir-lang.org/getting_started/1.html&quot;&gt;Tutorial&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;The 30 Days of Elixir &lt;a href=&quot;https://github.com/seven1m/30-days-of-elixir&quot;&gt;Repository&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Learning X in Y Minutes: &lt;a href=&quot;http://learnxinyminutes.com/docs/elixir/&quot;&gt;Where X = Elixir&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;The &lt;a href=&quot;http://media.pragprog.com/titles/elixir/ElixirCheat.pdf&quot;&gt;Elixir Cheat Sheet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


  &lt;p&gt;&lt;a href=&quot;/learning-elixir/&quot;&gt;Learning Elixir&lt;/a&gt; was originally published by Brian Gianforcaro at &lt;a href=&quot;&quot;&gt;bjg.io&lt;/a&gt; on November 30, 2014.&lt;/p&gt;</content>
</entry>


<entry>
  <title type="html"><![CDATA[Article: The Network is Reliable]]></title>
  <link rel="alternate" type="text/html" href="/distributed-systems/network-reliable/" />
  <id>/distributed-systems/network-reliable</id>
  <published>2014-11-04T00:00:00+00:00</published>
  <updated>2014-11-04T00:00:00+00:00</updated>
  <author>
    <name>Brian Gianforcaro</name>
    <uri></uri>
    <email>b.gianfo@gmail.com</email>
  </author>
  <content type="html">&lt;p&gt;&lt;a href=&quot;http://queue.acm.org/detail.cfm?id=2655736&quot;&gt;
&lt;img style=&quot;float:right; margin-left: 10px; margin-bottom: -10px;&quot; src=&quot;/images/network-reliable-thumb.png&quot; /&gt;
&lt;/a&gt;
One of my favorite excerpts from the article:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;h4 id=&quot;drbd-split-brain&quot;&gt;DRBD Split-brain&lt;/h4&gt;
  &lt;p&gt;When a two-node cluster partitions, there are no cases in which a node can reliably declare itself to be the primary. When this happens to a DRBD file system, as one user reported (&lt;a href=&quot;http://serverfault.com/questions/485545/dual-primary-ocfs2-drbd-encountered-split-brain-is-recovery-always-going-to-be&quot;&gt;http://serverfault.com/questions/485545/dual-primary-ocfs2-drbd-encountered-split-brain-is-recovery-always-going-to-be&lt;/a&gt;), both nodes can remain online and accept writes, leading to divergent file system-level changes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this article, &lt;a href=&quot;http://www.bailis.org/&quot;&gt;Peter Bailis&lt;/a&gt; and &lt;a href=&quot;http://aphyr.com/&quot;&gt;Kyle Kingsbury&lt;/a&gt; provide an awesome sampling of real life network failures
in a variety of actively deployed distributed systems.&lt;/p&gt;

&lt;p&gt;It’s definitely worth the read, especially interesting given the data from Google, Amazon, and Microsoft. You can view the living version of the document on github: &lt;a href=&quot;https://github.com/aphyr/partitions-post&quot;&gt;https://github.com/aphyr/partitions-post&lt;/a&gt;.&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;/distributed-systems/network-reliable/&quot;&gt;Article: The Network is Reliable&lt;/a&gt; was originally published by Brian Gianforcaro at &lt;a href=&quot;&quot;&gt;bjg.io&lt;/a&gt; on November 04, 2014.&lt;/p&gt;</content>
</entry>


<entry>
  <title type="html"><![CDATA[Embracing The Mirage [Part One]]]></title>
  <link rel="alternate" type="text/html" href="/systems/Embracing-The-Mirage/" />
  <id>/systems/Embracing-The-Mirage</id>
  <updated>2014-10-20T00:00:00-00:00</updated>
  <published>2014-09-22T00:00:00+00:00</published>
  
  <author>
    <name>Brian Gianforcaro</name>
    <uri></uri>
    <email>b.gianfo@gmail.com</email>
  </author>
  <content type="html">&lt;p&gt;As of late I have become increasingly enamored with this great research project &lt;a href=&quot;http://www.openmirage.org/&quot;&gt;Mirage OS&lt;/a&gt;.
The team is building a library operating system, they use the term &lt;a href=&quot;http://anil.recoil.org/papers/2013-asplos-mirage.pdf&quot;&gt;unikernel&lt;/a&gt;.
In essence this means that you write the code for your system, and at compilation time the system builds you an image which you can then
deploy to a &lt;a href=&quot;http://en.wikipedia.org/wiki/Hypervisor&quot;&gt;hypervisor&lt;/a&gt; running on bare metal. This image is then run virtualized, entirely on its own.
No operating system is needed to host your application, resulting the ability to better utilize cloud resources (less overhead) and much better isolation
guarantees due to VM &lt;a href=&quot;http://en.wikipedia.org/wiki/Sandbox_(computer_security)&quot;&gt;sandboxing&lt;/a&gt; which is inherit in virtualized environments.&lt;/p&gt;

&lt;p&gt;Besides the promises of isolation and efficiency, I’m also interested in the project because of the team’s choice of language for implementing their
library OS. They have chosen to use the &lt;a href=&quot;https://ocaml.org/&quot;&gt;OCaml&lt;/a&gt; language, for the uninitiated OCaml is an awesome language. It has inspired tons of other
languages that you might use everyday. OCaml has an great type system, which allows for quite in depth static analysis to be performed during compilation.
It has full support for functional, imperative, and object oriented programming styles.&lt;/p&gt;

&lt;p&gt;To me the project appears to be a recipe for success, and I want to help Mirage OS become even more successful.
The project currently has the ability to compile down to both &lt;a href=&quot;http://en.wikipedia.org/wiki/Xen&quot;&gt;Xen&lt;/a&gt; images, as well as unix user space process.
In the coming months, I will be working on adding user space windows process support, as well as a future goal of supporting &lt;a href=&quot;http://en.wikipedia.org/wiki/Hyper-V&quot;&gt;Hyper-V&lt;/a&gt; images.&lt;/p&gt;

&lt;p&gt;I’ve &lt;a href=&quot;http://lists.xenproject.org/archives/html/mirageos-devel/2014-09/msg00112.html&quot;&gt;expressed my interest&lt;/a&gt; to the Mirage OS developers mailing list, and they seem to agree this would be valuable work.
This is super exciting to me, and although there are many challenges ahead I’m sure I will learn a ton.&lt;/p&gt;

&lt;p&gt;I’ll be documenting the journey here.&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;/systems/Embracing-The-Mirage/&quot;&gt;Embracing The Mirage [Part One]&lt;/a&gt; was originally published by Brian Gianforcaro at &lt;a href=&quot;&quot;&gt;bjg.io&lt;/a&gt; on September 22, 2014.&lt;/p&gt;</content>
</entry>


<entry>
  <title type="html"><![CDATA[How To Kill An Azure Linux VM in One Second]]></title>
  <link rel="alternate" type="text/html" href="/virtualization/how-to-kill-an-azure-linux-vm/" />
  <id>/virtualization/how-to-kill-an-azure-linux-vm</id>
  <updated>2014-09-20T00:00:00-00:00</updated>
  <published>2014-09-20T00:00:00+00:00</published>
  
  <author>
    <name>Brian Gianforcaro</name>
    <uri></uri>
    <email>b.gianfo@gmail.com</email>
  </author>
  <content type="html">&lt;p&gt;It’s super easy, just try to install the Xen HyperVisor on the Ubuntu 14.0 Image.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-tcsh&quot; data-lang=&quot;tcsh&quot;&gt;&amp;gt; sudo apt-get install xen-system-amd64
&amp;gt; reboot&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The machine will never come up, as it will be hung on boot.
This appears to stem from the fact that &lt;a href=&quot;http://en.wikipedia.org/wiki/Hyper-V&quot;&gt;Hyper-V&lt;/a&gt; does not support nesting &lt;a href=&quot;http://en.wikipedia.org/wiki/Hypervisor&quot;&gt;Hypervisors&lt;/a&gt;.&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;/virtualization/how-to-kill-an-azure-linux-vm/&quot;&gt;How To Kill An Azure Linux VM in One Second&lt;/a&gt; was originally published by Brian Gianforcaro at &lt;a href=&quot;&quot;&gt;bjg.io&lt;/a&gt; on September 20, 2014.&lt;/p&gt;</content>
</entry>

</feed>
