<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Kevin Sookocheff</title>
    <link>https://sookocheff.com/</link>
    <description>Recent content on Kevin Sookocheff</description>
    <generator>Hugo</generator>
    <language>en-ca</language>
    <lastBuildDate>Mon, 15 Jun 2026 05:41:48 +0000</lastBuildDate>
    <atom:link href="https://sookocheff.com/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Building your own Tool Calling Agent</title>
      <link>https://sookocheff.com/post/ai/building-your-own-tool-calling-agent/</link>
      <pubDate>Mon, 15 Jun 2026 05:41:48 +0000</pubDate>
      <guid>https://sookocheff.com/post/ai/building-your-own-tool-calling-agent/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Any sufficiently advanced technology is indistinguishable from magic.&lt;/p&gt;
&lt;p&gt;— &lt;cite&gt;Arthur C. Clarke&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;At times I feel like Claude Code is this magical black box that I can
give tasks to and get working code out of. This post attempts to shine
a light on that black box by building our own agent harness around
a model.&lt;/p&gt;
&lt;p&gt;To do this, I will use Anthropic’s API to build a simple code review
harness, showing how to take a simple chatbot interface into a fully
featured developer application.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Seven Powers of Platform Teams</title>
      <link>https://sookocheff.com/post/business/seven-powers-of-platform-teams/</link>
      <pubDate>Sun, 10 May 2026 09:18:32 +0000</pubDate>
      <guid>https://sookocheff.com/post/business/seven-powers-of-platform-teams/</guid>
      <description>&lt;p&gt;I work on Workiva’s cloud platform engineering team, where we design and
operate Kubernetes and AWS infrastructure supporting more than 300
microservices across multiple AWS regions. The platform spans networking,
observability, CI/CD, compliance, and internal developer tooling. Lately,
our team has been busy developing and codifying our strategy. I’m not
a big fan of reinventing the wheel, and neither is the rest of our team,
so we welcomed the opportunity to use existing business strategy
frameworks and methodologies as a way to get started quickly. We used the
&lt;a href=&#34;https://fs.blog/playing-to-win-how-strategy-really-works/&#34;&gt;Playing to Win
Framework&lt;/a&gt;,
and were able to flesh out a meaningful strategy focusing on things such
as reducing cognitive load for development teams and streamlining how we
report the customer impact of incidents.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Human in the Core, AI in the Shell</title>
      <link>https://sookocheff.com/post/ai/human-core-ai-shell/</link>
      <pubDate>Thu, 02 Apr 2026 05:41:48 +0000</pubDate>
      <guid>https://sookocheff.com/post/ai/human-core-ai-shell/</guid>
      <description>&lt;p&gt;I, like many of you, am wrestling with how to best apply AI to my career
as a software engineer. As we continue to adopt to AI-assisted coding,
there is becoming &lt;a href=&#34;https://arxiv.org/abs/2506.08872&#34;&gt;more&lt;/a&gt; and
&lt;a href=&#34;https://www.anthropic.com/research/AI-assistance-coding-skills&#34;&gt;more&lt;/a&gt;
evidence that we may be limiting the ability of our future selves to own
and support software systems.&lt;/p&gt;
&lt;p&gt;In &lt;a href=&#34;https://sookocheff.com/post/ai/blogging-in-the-age-of-ai/&#34;&gt;my last post&lt;/a&gt;, I made the
argument that by writing this blog by hand, it forced a deeper
understanding of the material, and resulted in something I was proud to
call my own. Leveraging AI for writing removed both of these benefits,
and stripped the satisfaction I get from having a blog in the first
place.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Blogging in the Age of AI</title>
      <link>https://sookocheff.com/post/ai/blogging-in-the-age-of-ai/</link>
      <pubDate>Mon, 16 Mar 2026 05:41:48 +0000</pubDate>
      <guid>https://sookocheff.com/post/ai/blogging-in-the-age-of-ai/</guid>
      <description>&lt;p&gt;This blog has been a part of my life for over fifteen years ago.&lt;/p&gt;
&lt;p&gt;When I first started, I was inspired by Patrick McKenzie’s article &lt;a href=&#34;https://training.kalzumeus.com/newsletters/archive/do-not-end-the-week-with-nothing&#34;&gt;Don’t
End The Week With
Nothing&lt;/a&gt;.
This post left a memorable impression on 20-something me who had yet to
consider what work really was — trading time and (sometimes) skill for
money.&lt;/p&gt;
&lt;p&gt;You work for a week, collect your paycheck on Friday, and then you and
the company are even. If you are happy settling for even, that’s great.
But then how can you get ahead? What would it take to finish a week with
more than a break-even trade of time for money? Here I will quote Patrick
verbatim:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Controlling a Korg Volca with the Akai MPK Mini Plus</title>
      <link>https://sookocheff.com/post/music/controlling-korg-volca-with-akia-mpk-mini-plus/</link>
      <pubDate>Fri, 16 Jan 2026 09:21:32 +0000</pubDate>
      <guid>https://sookocheff.com/post/music/controlling-korg-volca-with-akia-mpk-mini-plus/</guid>
      <description>&lt;p&gt;In an attempt to move more of my music workflow off of my Mac and onto
real hardware, I recently bought a set of used &lt;a href=&#34;https://www.korg-volca.com/en/&#34;&gt;Korg
Volca&lt;/a&gt; synthesizers for experimenting
with synthesis and drum programming. I also have an &lt;a href=&#34;https://www.akaipro.com/mpk-mini-plus/&#34;&gt;Akai MPK mini
plus&lt;/a&gt; that I mainly used for
controlling &lt;a href=&#34;https://www.apple.com/ca/logic-pro/&#34;&gt;Logic Pro&lt;/a&gt; that
I wanted to repurpose for controlling the Volca synths through the MIDI
out on the Akai MPK mini.&lt;/p&gt;
&lt;p&gt;Since I couldn’t find any existing documentation of the process,
I thought I would write it down myself in hopes of helping the next
person working through this setup. This set of steps should be easily
adaptable to both the MPK mini IV controller and other MIDI controllable
synths or devices.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cryptography for the Everyday Developer: Understanding RSA</title>
      <link>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/understanding-rsa/</link>
      <pubDate>Fri, 05 Dec 2025 10:52:43 -0600</pubDate>
      <guid>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/understanding-rsa/</guid>
      <description>&lt;p&gt;&lt;em&gt;This is an article in a series on &lt;a href=&#34;https://sookocheff.com/series/cryptography-for-the-everyday-developer/&#34;&gt;Cryptography for the Everyday
Developer&lt;/a&gt;. Follow
along to learn the basics of modern cryptography and encryption.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Before the late 1970s, secure communication largely meant symmetric
encryption. This included the complexity that comes with maintaining and
sharing secrets every time two parties wished to communicate. RSA changed
that by showing that encryption and decryption could use different keys,
making secure communication practical for applications across the
Internet.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cryptography for the Everyday Developer: Number Theory for Public Key Cryptography</title>
      <link>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/euclidean-algorithm-and-public-key-cryptography/</link>
      <pubDate>Tue, 07 Oct 2025 06:04:32 -0600</pubDate>
      <guid>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/euclidean-algorithm-and-public-key-cryptography/</guid>
      <description>&lt;p&gt;&lt;em&gt;This is an article in a series on &lt;a href=&#34;https://sookocheff.com/series/cryptography-for-the-everyday-developer/&#34;&gt;Cryptography for the Everyday
Developer&lt;/a&gt;. Follow
along to learn the basics of modern cryptography and encryption.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Modern cryptography relies heavily on number theory. One of the simplest
but most important tools in the number theorist’s toolkit is
the Euclidean algorithm. This algorithm, and its extension, the extended
Euclidean algorithm, form the basis for practical cryptographic
operations such as modular inversion. This blog post walks through both
algorithms, with an explanation of why they are important to public key
cryptography.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why Three Replicas Are Better Than Two</title>
      <link>https://sookocheff.com/post/kubernetes/why-three-replicas-are-better-than-two/</link>
      <pubDate>Thu, 02 Oct 2025 09:40:16 +0000</pubDate>
      <guid>https://sookocheff.com/post/kubernetes/why-three-replicas-are-better-than-two/</guid>
      <description>&lt;p&gt;When deploying microservices on Kubernetes, how many replicas should
I run? Intuition suggests that two replicas is enough to give you high
availability; if one pod dies, the other keeps the service online.
Industry standard, however, suggests running three replicas. Why is this
the case?&lt;/p&gt;
&lt;p&gt;In this post, I will explain reasons to choose three replicas over two,
and some best practices based on the realities specific to Kubernetes.&lt;/p&gt;
&lt;h2 id=&#34;the-math-behind-preferring-three-replicas&#34;&gt;The Math Behind Preferring Three Replicas&lt;/h2&gt;
&lt;p&gt;The suggestion to run three replicas is often followed by hand-wavy
“because it is more resilient”. Rather than rely on intuition, let’s try
putting some numbers behind the reasoning.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cryptography for the Everyday Developer: Double Encryption and the Meet in the Middle Attack</title>
      <link>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/meet-in-the-middle-attack/</link>
      <pubDate>Wed, 24 Sep 2025 10:04:32 -0600</pubDate>
      <guid>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/meet-in-the-middle-attack/</guid>
      <description>&lt;p&gt;&lt;em&gt;This is an article in a series on &lt;a href=&#34;https://sookocheff.com/series/cryptography-for-the-everyday-developer/&#34;&gt;Cryptography for the Everyday
Developer&lt;/a&gt;. Follow
along to learn the basics of modern cryptography and encryption.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;When the Data Encryption Standard (DES) was introduced in the 1970s, it
was considered a solid block cipher. But DES has one major flaw by
today’s standards — a small key space. With only 56 bits of key material,
DES can be brute-forced with modern hardware by checking every possible
key value. Once it was apparent that DES was no longer secure and could
be brute-forced, a natural idea to extend the life of DES without
resorting to an entirely new algorithm was to increase the size of the
key space by encrypting the data twice with two different keys. The hope
was that doubling the encryption operation with different keys would
increase the difficulty of brute force attacks.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cryptography for the Everyday Developer: Understanding AES - The Advanced Encryption Standard</title>
      <link>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/aes/</link>
      <pubDate>Fri, 22 Aug 2025 09:08:32 -0600</pubDate>
      <guid>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/aes/</guid>
      <description>&lt;p&gt;&lt;em&gt;This is an article in a series on &lt;a href=&#34;https://sookocheff.com/series/cryptography-for-the-everyday-developer/&#34;&gt;Cryptography for the Everyday
Developer&lt;/a&gt;. Follow
along to learn the basics of modern cryptography and encryption.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Last time we explored the &lt;a href=&#34;https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/des/&#34;&gt;Data Encryption Standard (DES)&lt;/a&gt;, and how its Feistel network structure worked. We also saw why DES
eventually became obsolete: its 56-bit key size was simply too small in
the face of modern computing power.&lt;/p&gt;
&lt;p&gt;To replace DES, the U.S. National Institute of Standards and Technology
(NIST) held a public competition in the late 1990s. Fifteen different
algorithms were submitted from around the world. Over the course of
several years, this field was narrowed down to five finalists, each
carefully analyzed by cryptographers. Finally, in 2000, an algorithm
called Rijndael, created by two Belgian cryptographers, Joan Daemen and
Vincent Rijmen, was selected as the winner. This became the Advanced
Encryption Standard (AES), which has since become the most widely used
block cipher in the world. It is used everywhere: encrypting TLS traffic
in your browser, securing Wi-Fi connections, and protecting classified
government data.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cryptography for the Everyday Developer: Understanding DES - The Data Encryption Standard</title>
      <link>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/des/</link>
      <pubDate>Fri, 18 Jul 2025 09:04:32 -0600</pubDate>
      <guid>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/des/</guid>
      <description>&lt;p&gt;&lt;em&gt;This is an article in a series on &lt;a href=&#34;https://sookocheff.com/series/cryptography-for-the-everyday-developer/&#34;&gt;Cryptography for the Everyday
Developer&lt;/a&gt;. Follow
along to learn the basics of modern cryptography and encryption.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The Data Encryption Standard (DES) is based upon the principles of
a substitution-permutation network that we learned about in the &lt;a href=&#34;https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/confusion-diffusion-and-substitution-permutation-networks/&#34;&gt;last
post in this series&lt;/a&gt;. The design of DES is based on the principles of &lt;a href=&#34;https://en.wikipedia.org/wiki/Feistel_cipher&#34;&gt;Feistel
ciphers&lt;/a&gt;, which are
a particular configuration of a substitution-permutation network
developed by Horst Feistel at IBM.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cryptography for the Everyday Developer: Confusion, Diffusion, and Substitution-Permutation Networks</title>
      <link>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/confusion-diffusion-and-substitution-permutation-networks/</link>
      <pubDate>Fri, 06 Jun 2025 09:04:32 -0600</pubDate>
      <guid>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/confusion-diffusion-and-substitution-permutation-networks/</guid>
      <description>&lt;p&gt;&lt;em&gt;This is an article in a series on &lt;a href=&#34;https://sookocheff.com/series/cryptography-for-the-everyday-developer/&#34;&gt;Cryptography for the Everyday
Developer&lt;/a&gt;. Follow
along to learn the basics of modern cryptography and encryption.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;A &lt;em&gt;block cipher&lt;/em&gt; is a type if cipher that combines an
encryption/decryption algorithm that works on blocks of data with a &lt;em&gt;mode
of operation&lt;/em&gt; that details the techniques to process sequences of data
blocks.&lt;/p&gt;
&lt;p&gt;While many different block cipher algorithms exist, they all share
a common structural design: they apply a series of transformations
— known as rounds — that iteratively manipulate the input data. These
rounds consist of small, repeatable operations that gradually transform
the plaintext into ciphertext.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Using V2 CloudFront Logs via CloudFormation</title>
      <link>https://sookocheff.com/post/aws/using-v2-logging-with-cloudfront-via-cloudformation/</link>
      <pubDate>Thu, 22 May 2025 11:02:03 +0000</pubDate>
      <guid>https://sookocheff.com/post/aws/using-v2-logging-with-cloudfront-via-cloudformation/</guid>
      <description>&lt;p&gt;CloudFront supports two logging modes: &lt;a href=&#34;https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/standard-logging.html&#34;&gt;v2
logging&lt;/a&gt;
and &lt;a href=&#34;https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/standard-logging-legacy-s3.html&#34;&gt;legacy
logging&lt;/a&gt;.
Naturally, you&amp;rsquo;d expect to use the newer v2 logging—but if you&amp;rsquo;re
provisioning CloudFront with CloudFormation, it&amp;rsquo;s easy to end up with the
legacy setup by accident.&lt;/p&gt;
&lt;p&gt;If you use the &lt;code&gt;Logging&lt;/code&gt;
&lt;a href=&#34;https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-logging.html&#34;&gt;property&lt;/a&gt;
in your &lt;code&gt;AWS::CloudFront::Distribution&lt;/code&gt;, CloudFormation &lt;strong&gt;will default to
legacy logging&lt;/strong&gt;, writing directly to S3. There’s currently no way to
switch this to v2 via the &lt;code&gt;Logging&lt;/code&gt; property in CloudFormation.&lt;/p&gt;
&lt;p&gt;To enable &lt;strong&gt;v2 logging&lt;/strong&gt;, you have to take a different approach:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Fixing display flicker for Dell monitors on Apple Silicon</title>
      <link>https://sookocheff.com/post/tools/fixing-display-flicker-dell-monitor-apple-silicon/</link>
      <pubDate>Thu, 24 Apr 2025 06:14:23 +0000</pubDate>
      <guid>https://sookocheff.com/post/tools/fixing-display-flicker-dell-monitor-apple-silicon/</guid>
      <description>&lt;p&gt;If you have a Dell monitor and an M-series chip from Apple, you may have
encountered flickering issues with your monitor which — at times — can
render it completely unusable. The issue appears to be &lt;a href=&#34;https://www.reddit.com/r/Dell/comments/1jlshnu/monitor_flicker_on_m_series_chip/&#34;&gt;fairly&lt;/a&gt;
&lt;a href=&#34;https://www.reddit.com/r/Dell/comments/u405lh/m1_mac_dell_monitor_flickering_issue_fixed/&#34;&gt;widespread&lt;/a&gt;
and can affect a number of Dell model and Apple silicon chip
combinations, and has been acknowledged by
&lt;a href=&#34;https://www.dell.com/support/kbdoc/en-us/000202717/certain-dell-monitors-have-flickering-video-with-apple-m1-macs&#34;&gt;Dell&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The flicker is caused by the monitors LCD panel’s Image Compensation
Algorithm (ICA) function repeatedly turning On and Off. The YCbCr Video
generated from the Macs is at 17Gray level, it fluctuates between
15Gary and 17Gary. Hence it is repeatedly turning On and Off, the ICA
which has a threshold setting of 16Gray.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cryptography for the Everyday Developer: Measuring Security in Bits</title>
      <link>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/measuring-security-in-bits/</link>
      <pubDate>Thu, 20 Mar 2025 10:04:32 -0600</pubDate>
      <guid>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/measuring-security-in-bits/</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the fifth article in a series on &lt;a href=&#34;https://sookocheff.com/series/cryptography-for-the-everyday-developer/&#34;&gt;Cryptography for the Everyday
Developer&lt;/a&gt;.
Follow along to learn the basics of modern cryptography and encryption.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;When discussing encryption, you&amp;rsquo;ll often hear talk about the strength of
a security system as measured in “bits.” For example, systems might
advertise their strength as having 128-bits or 256-bits. But what exactly
does security measured in bits mean? Let&amp;rsquo;s demystify this common yet
sometimes misunderstood concept.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cryptography for the Everyday Developer: Modular Arithmetic</title>
      <link>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/modular-arithmetic/</link>
      <pubDate>Mon, 17 Mar 2025 10:04:32 -0600</pubDate>
      <guid>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/modular-arithmetic/</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the fourth article in a series on &lt;a href=&#34;https://sookocheff.com/series/cryptography-for-the-everyday-developer/&#34;&gt;Cryptography for the Everyday
Developer&lt;/a&gt;.
Follow along to learn the basics of modern cryptography and encryption.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Modular arithmetic is the foundation for asymmetric cryptography like
RSA, elliptic curves, or Diffie-Hellman — all of them rely on the
properties of modular arithmetic to guarantee security and secrecy.&lt;/p&gt;
&lt;p&gt;Since modular arithmetic is so important to cryptography, it pays to
understand how it works. This post will help us along the journey by
demystifying modular arithmetic, explaining how it works, and why it
matters for cryptography.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cryptography for the Everyday Developer: Random Number Generators</title>
      <link>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/randomness/</link>
      <pubDate>Fri, 14 Feb 2025 10:52:43 -0600</pubDate>
      <guid>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/randomness/</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the third article in a series on &lt;a href=&#34;https://sookocheff.com/series/cryptography-for-the-everyday-developer/&#34;&gt;Cryptography for the Everyday
Developer&lt;/a&gt;. Follow
along to learn the basics of modern cryptography and encryption.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;Without randomness, cryptography would be impossible because all
operations would become predictable and therefore insecure.&lt;/p&gt;
&lt;p&gt;— &lt;cite&gt;Jean-Philippe Aumasson, &lt;a href=&#34;https://www.amazon.ca/Serious-Cryptography-2nd-Introduction-Encryption-dp-1718503849/dp/1718503849&#34;&gt;Serious Cryptography&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The cryptographic strength of most systems lies in their ability to generate
random numbers that cannot be easily guessed or reproduced, making it difficult
for adversaries to crack the encryption or predict the output.  Unfortunately
for us, computers and the software that they run are very predictable. As long
as they are given the same inputs each time, they’ll always come up with the
same outputs. This is very good for reliability, but not so good for
cryptography where randomness and unpredictability are required for secure
operation.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cryptography for the Everyday Developer: Security Goals</title>
      <link>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/security-goals/</link>
      <pubDate>Tue, 28 Jan 2025 10:52:43 -0600</pubDate>
      <guid>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/security-goals/</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the second article in a series on &lt;a href=&#34;https://sookocheff.com/series/cryptography-for-the-everyday-developer/&#34;&gt;Cryptography for the Everyday
Developer&lt;/a&gt;. Follow
along to learn the basics of modern cryptography and encryption.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;A cipher is only useful if it is secure. What makes a cipher secure?
Let’s remember the use case for &lt;a href=&#34;https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/encryption-basics-with-classical-ciphers/&#34;&gt;classical ciphers&lt;/a&gt; — keeping messages &lt;em&gt;confidential&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Caesar’s cipher and Vigenère’s cipher both suffer from a similar flaw,
which makes them insecure and unusable for secure communication. For both
ciphers, the flaw is obvious — these ciphers allow an attacker to learn
how the cipher works by inspecting the ciphertext itself. This allows an
eavesdropper can decrypt the message given only the ciphertext. A secure
cipher, on the other hand, is one where it is not possible to learn
anything about the plaintext or the cipher’s behaviour even by inspecting
numerous plaintext or ciphertext messages.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cryptography for the Everyday Developer: Encryption Basics with Classical Ciphers</title>
      <link>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/encryption-basics-with-classical-ciphers/</link>
      <pubDate>Wed, 22 Jan 2025 10:04:32 -0600</pubDate>
      <guid>https://sookocheff.com/post/cryptography/cryptography-for-the-everyday-developer/encryption-basics-with-classical-ciphers/</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the first article in a series on &lt;a href=&#34;https://sookocheff.com/series/cryptography-for-the-everyday-developer/&#34;&gt;Cryptography for the Everyday
Developer&lt;/a&gt;.
Follow along to learn the basics of modern cryptography and encryption.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The best way to begin learning about encryption is by example. And
thankfully, there exist many examples of encryption throughout history
that we can draw from. One of the earliest well-known examples of
encryption is the &lt;em&gt;Caesar Cipher&lt;/em&gt;, and we will begin there.&lt;/p&gt;
&lt;p&gt;The Caesar cipher is one of the oldest and simplest forms of encryption.
It works by shifting each letter in your message a fixed number of
positions down the alphabet. For example, with a shift of 3:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Clustering a DSM Using Simulated Annealing</title>
      <link>https://sookocheff.com/post/dsm/clustering-a-dsm-using-simulated-annealing/</link>
      <pubDate>Fri, 10 Jan 2025 05:48:21 -0600</pubDate>
      <guid>https://sookocheff.com/post/dsm/clustering-a-dsm-using-simulated-annealing/</guid>
      <description>&lt;p&gt;In this blog post, we will explore how to use simulated annealing to cluster a
Design Structure Matrix (DSM). We will also discuss how this approach differs
from the implementation developed by Ronnie Thebeau as part of his master&amp;rsquo;s
thesis.&lt;/p&gt;
&lt;h2 id=&#34;what-is-a-design-structure-matrix-dsm&#34;&gt;What is a Design Structure Matrix (DSM)?&lt;/h2&gt;
&lt;p&gt;A Design Structure Matrix (DSM) is a compact, matrix representation of a system
or project. It is used to model the relationships between elements in a system,
such as tasks in a project or components in a product. Each row and column in
the matrix represents an element, and the cells indicate the presence and
strength of relationships between elements.&lt;/p&gt;</description>
    </item>
    <item>
      <title>In the Cloud, Cost is Everything</title>
      <link>https://sookocheff.com/post/architecture/in-the-cloud-cost-is-everything/</link>
      <pubDate>Tue, 17 Dec 2024 12:49:38 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/in-the-cloud-cost-is-everything/</guid>
      <description>&lt;p&gt;At AWS re:Invent 2023, Amazon CTO Werner Vogels delivered
a &lt;a href=&#34;https://www.youtube.com/watch?v=UTRBVPvzt9w&#34;&gt;talk&lt;/a&gt; on the &lt;a href=&#34;https://thefrugalarchitect.com/laws/&#34;&gt;laws of
frugal architecture&lt;/a&gt;. While
I initially filed away those insights to review later, a year of cloud
architecture experience crystallized a fundamental truth: in cloud
computing, cost isn&amp;rsquo;t just a financial consideration — it is
a first-class architectural concern through which we should design and
optimize our systems.&lt;/p&gt;
&lt;p&gt;Cloud providers charge for every conceivable resource: servers, API
calls, data transfer, and computational milliseconds. But cost is more
than just a line item on a monthly bill, it is a powerful forcing
function that drives better architectural decisions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Developers Guide to FIPS 140 Compliance</title>
      <link>https://sookocheff.com/post/compliance/the-developers-guide-to-fips-compliance/</link>
      <pubDate>Thu, 06 Jun 2024 11:15:08 +0000</pubDate>
      <guid>https://sookocheff.com/post/compliance/the-developers-guide-to-fips-compliance/</guid>
      <description>&lt;p&gt;If you work with US government entities or corporations in regulated
markets the subject of FIPS compliance may come up, especially in the
context of FedRAMP authorization. FIPS 140-2 and FIPS 140-3 are a set of
cryptographic standards that your application may need to adhere to
dictating the appropriate ciphers or cryptographic functions that are in
use.&lt;/p&gt;
&lt;p&gt;It can take a lot of effort to run a completely FIPS compliant
architecture, but for application developers, the bottom line is that any
code that uses cryptographic operations to secure customer data must use
FIPS certified cryptographic libraries.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Near infinite scaling with the scale cube and cell-based architecture</title>
      <link>https://sookocheff.com/post/architecture/scaling-with-workload-separation/</link>
      <pubDate>Tue, 28 May 2024 03:38:23 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/scaling-with-workload-separation/</guid>
      <description>&lt;p&gt;Most new applications are built as a single codebase and deployed as
a monolith until product-market fit or the need for additional scale is
required. Such monolithic applications are easy to write and maintain,
and allow you to iterate quickly when there are a smaller number of users
and the traffic is low. However, as traffic increases you will need to
scale the application to handle the increase in load. One framework for
scaling is the “Scale Cube” describe by &lt;a href=&#34;https://akfpartners.com/growth-blog/scale-cube&#34;&gt;AKF partners&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Developing an Aya-rs eBPF application using devcontainers</title>
      <link>https://sookocheff.com/post/kubernetes/developing-an-aya-rs-app-using-devcontainers/</link>
      <pubDate>Wed, 08 May 2024 10:14:21 -0600</pubDate>
      <guid>https://sookocheff.com/post/kubernetes/developing-an-aya-rs-app-using-devcontainers/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://ebpf.io/&#34;&gt;eBPF&lt;/a&gt; is a technology allowing you to dynamically
program the kernel using a virtual machine approach. Several &lt;a href=&#34;https://sookocheff.com/post/ebpf/surveying-the-ebpf-developer-ecosystem/&#34;&gt;development
frameworks&lt;/a&gt; exist,
with the top choice for Rust developers being
&lt;a href=&#34;https://github.com/aya-rs/aya&#34;&gt;Aya&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Because of the deep integration between eBPF and the Linux kernel, it can
be challenging to create a local development environment that works
across different development machines. To date, I’ve taken to developing
eBPF programs on EC2 instances using the AWS Cloud9 development
environment. This works, but comes with its own issues and won’t be for
everyone.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Building a FIPS Compliant Kubernetes Cluster on AWS</title>
      <link>https://sookocheff.com/post/aws/building-a-fips-compliant-kubernetes-cluster-on-aws/</link>
      <pubDate>Thu, 18 Apr 2024 11:59:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/aws/building-a-fips-compliant-kubernetes-cluster-on-aws/</guid>
      <description>&lt;p&gt;One of the larger hurdles to climb when becoming FedRamp moderate is
encrypting all data in transit using FIPS validated encryption modules.
This article describes one approach to satisfying this requirement for
anyone running a Kubernetes cluster on AWS.&lt;/p&gt;
&lt;p&gt;For those lucky souls who are unfamiliar with FIPS, it stands for Federal
Information Processing Standard (FIPS), which is a joint US and Canadian
government standard that specifies the security requirements for
cryptographic modules that protect sensitive information. FedRamp
specifically requires you to satisfy two related controls: SC-8 and
SC-13.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Surveying the eBPF Developer Ecosystem</title>
      <link>https://sookocheff.com/post/ebpf/surveying-the-ebpf-developer-ecosystem/</link>
      <pubDate>Fri, 22 Mar 2024 05:48:21 -0600</pubDate>
      <guid>https://sookocheff.com/post/ebpf/surveying-the-ebpf-developer-ecosystem/</guid>
      <description>&lt;p&gt;This article provides guide to the different developer tools available
for writing eBPF programs, covering the core tools
&lt;a href=&#34;https://github.com/iovisor/bcc&#34;&gt;BCC&lt;/a&gt;,
&lt;a href=&#34;https://github.com/iovisor/bpftrace&#34;&gt;bpftrace&lt;/a&gt;,
&lt;a href=&#34;https://ebpf-go.dev/&#34;&gt;ebpf-go&lt;/a&gt;, and
&lt;a href=&#34;https://github.com/libbpf/libbpf&#34;&gt;libbpf&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;These tools satisfy a different use case depending on whether you are
trying to use eBPF for running analysis scripts, or full-fledged
programs, in what programming language you wish to use, and the maturity
and feature parity with the most recent eBPF features in the Linux
kernel.&lt;/p&gt;
&lt;p&gt;Unfortunately, there is no single definitive guide to BPF and
there is still a lot of unwritten knowledge, though some of the resources
provided in this article may help you get started on your own journey.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Routing Users to a Login Page Based on Geolocation</title>
      <link>https://sookocheff.com/post/aws/routing-users-to-a-login-page-based-on-geolocation/</link>
      <pubDate>Tue, 12 Dec 2023 11:42:33 +0000</pubDate>
      <guid>https://sookocheff.com/post/aws/routing-users-to-a-login-page-based-on-geolocation/</guid>
      <description>&lt;p&gt;A common pattern when scaling a SaaS application is to deploy your stack
to multiple regions across the globe. Deploying to multiple regions helps
distribute the application and data closer to the user, and isolates
infrastructure in case of an outage in a single region. If your
application is deployed in this configuration, you have the new problem
of routing users to the correct region based on their tenancy or
geography. This post shows how to create a global login portal that
directs users to the correct local region where they can access their
application.&lt;/p&gt;</description>
    </item>
    <item>
      <title>What is eBPF and Why is it Important?</title>
      <link>https://sookocheff.com/post/ebpf/what-is-ebpf-and-why-is-it-important/</link>
      <pubDate>Mon, 04 Dec 2023 05:48:21 -0600</pubDate>
      <guid>https://sookocheff.com/post/ebpf/what-is-ebpf-and-why-is-it-important/</guid>
      <description>&lt;p&gt;A short tagline from the book &lt;a href=&#34;https://www.oreilly.com/library/view/learning-ebpf/9781098135119/&#34;&gt;Learning
eBPF&lt;/a&gt;
describes eBPF as&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;a revolutionary kernel technology that allows developers to write
custom code that can be loaded into the kernel dynamically, changing
the way the kernel behaves.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The key word in this phrase is &lt;em&gt;dynamically&lt;/em&gt;. eBPF allows you to write custom
code that changes the way the kernel behaves without having to implement
a kernel module or integrate your code directly into the kernel.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Disaster Recovery with DynamoDB Global Tables</title>
      <link>https://sookocheff.com/post/aws/disaster-recovery-with-dynamodb-global-tables/</link>
      <pubDate>Mon, 20 Nov 2023 11:59:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/aws/disaster-recovery-with-dynamodb-global-tables/</guid>
      <description>&lt;p&gt;DynamoDB provides built-in support for cross regional data replication
using a solution AWS calls &lt;em&gt;global tables&lt;/em&gt;. This article shows how to
build and run an application in Kubernetes that uses global tables to
replicate data between regions. In the event of a regional disaster,
a secondary Kubernetes cluster in a secondary region has all the data
from DynamoDB replicated locally to continue operation.&lt;/p&gt;
&lt;h2 id=&#34;how-global-tables-work&#34;&gt;How global tables work&lt;/h2&gt;
&lt;p&gt;A DynamoDB global table is a set of multiple replica tables. Each replica
table exists in a different AWS region, but all replicas have the same
name and primary key. Whenever data is written to any replica table, the
data is automatically replicated to all other replica tables that have
been added to the global table.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Supporting disaster recovery with a multi-region EKS deployment</title>
      <link>https://sookocheff.com/post/kubernetes/disaster-recovery-with-eks/</link>
      <pubDate>Thu, 09 Nov 2023 10:14:21 -0600</pubDate>
      <guid>https://sookocheff.com/post/kubernetes/disaster-recovery-with-eks/</guid>
      <description>&lt;p&gt;Disaster events are one of the biggest challenges that a software
organization can face. Natural disasters like earthquakes or floods,
technical failures such as power or network loss, and human actions such
as unauthorized attacks can disable an entire fleet of systems, leading
to complete failure for a business. To deal with disaster scenarios
requires a proactive approach to prepare and recover from failure.&lt;/p&gt;
&lt;p&gt;One of the key benefits of running in the cloud is how easy it is to run
workloads in multiple regions. This allows you to deploy a resilient
architecture that supports disaster recovery, even in the cases where an
entire region is disabled.&lt;/p&gt;</description>
    </item>
    <item>
      <title>FSBench: A filesystem benchmarking utility</title>
      <link>https://sookocheff.com/post/performance/fsbench/</link>
      <pubDate>Fri, 22 Sep 2023 13:17:49 +0000</pubDate>
      <guid>https://sookocheff.com/post/performance/fsbench/</guid>
      <description>&lt;p&gt;Check out the project on &lt;a href=&#34;https://github.com/soofaloofa/fsbench&#34;&gt;Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I recently published a new project for repeatable filesystem
benchmarking. This code is based on the benchmarks available in the &lt;a href=&#34;https://github.com/awslabs/mountpoint-s3&#34;&gt;AWS
Mountpoint-s3&lt;/a&gt; project and the
&lt;a href=&#34;https://github.com/axboe/fio&#34;&gt;Flexible I/O Tester&lt;/a&gt;, made into a more
general purpose utility for benchmarking arbitrary filesystems.&lt;/p&gt;
&lt;p&gt;The benchmark consists of a mix of read and write workloads, each run for
ten iterations. The average result of the ten iterations is reported as
the final result of the benchmark.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Benchmarking AWS CSI Drivers</title>
      <link>https://sookocheff.com/post/kubernetes/benchmarking-aws-csi-drivers/</link>
      <pubDate>Tue, 19 Sep 2023 10:27:12 +0000</pubDate>
      <guid>https://sookocheff.com/post/kubernetes/benchmarking-aws-csi-drivers/</guid>
      <description>&lt;p&gt;AWS provides four different &lt;a href=&#34;https://sookocheff.com/post/kubernetes/picking-the-right-aws-csi-driver-for-your-kubernetes-application/&#34;&gt;storage options&lt;/a&gt; for your Kubernetes cluster: EBS, EFS, FSx for Lustre, and Amazon
File Cache. Each of these CSI drivers has different performance
characteristics, depending on your workload. This post quantifies those
performance differences using the flexible I/O tester
&lt;a href=&#34;https://github.com/axboe/fio&#34;&gt;FIO&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: For an overview of the different CSI options available on AWS,
see &lt;a href=&#34;https://sookocheff.com/post/kubernetes/picking-the-right-aws-csi-driver-for-your-kubernetes-application/&#34;&gt;Picking the right AWS CSI driver for your Kubernetes
application&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Before we start, please note that these results come with multiple
caveats, and you should absolutely test performance on your own workloads
before making any final decisions. For example, a workload with many
random reads is typically latency sensitive and would benefit from higher
IOPS, whereas a workload consisting of mostly streaming reads is
typically throughput sensitive and would benefit from higher bandwidth
and at large I/O sizes with relatively lower IOPS.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Picking the right AWS CSI driver for your Kubernetes application</title>
      <link>https://sookocheff.com/post/kubernetes/picking-the-right-aws-csi-driver-for-your-kubernetes-application/</link>
      <pubDate>Tue, 12 Sep 2023 06:44:23 -0600</pubDate>
      <guid>https://sookocheff.com/post/kubernetes/picking-the-right-aws-csi-driver-for-your-kubernetes-application/</guid>
      <description>&lt;p&gt;Dealing with storage is a core challenge when running complex
applications on Kubernetes. While many applications operate just fine
using a cloud database or blob storage, some applications have
performance or design requirements requiring local storage.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: For performance benchmarks see [Benchmarking AWS CSI Drivers](&amp;lt;{{ relref &amp;ldquo;/post/kubernetes/benchmarking-aws-csi-drivers&amp;rdquo; }}).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When this is the case, developers and cluster operators rely on
&lt;a href=&#34;https://kubernetes-csi.github.io/docs/&#34;&gt;Container Storage Interface
(CSI)&lt;/a&gt; implementations to provide
local storage for Pods. When running on the AWS cloud, no less than
&lt;em&gt;four&lt;/em&gt; CSI providers are available for us to use: Elastic Block Storage,
Elastic File System, FSx for Lustre, and AWS File Cache. This article
compares these four different local storage options to help you choose
the right option for your application.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Leveraging eBPF in the Kubernetes Networking Model</title>
      <link>https://sookocheff.com/post/kubernetes/leveraging-ebpf-in-the-kubernetes-networking-model/</link>
      <pubDate>Mon, 21 Aug 2023 03:48:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/kubernetes/leveraging-ebpf-in-the-kubernetes-networking-model/</guid>
      <description>&lt;p&gt;eBPF is a relatively new extension of the Linux kernel that can run
sandboxed programs in a privileged context. It is used to safely and
efficiently extend the capabilities of the kernel at runtime without
requiring changes to kernel source code or the loading of kernel modules.&lt;/p&gt;
&lt;p&gt;Because of eBPFs tight integration with the networking stack at the
kernel level, it is seeing adoption in networking applications. This
includes Kubernetes networking through eBPF implementations of the
Kubnernetes networking stack like &lt;a href=&#34;https://cilium.io/&#34;&gt;Cilium&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Trust your users — they’re usually right</title>
      <link>https://sookocheff.com/post/opinion/trust-your-users/</link>
      <pubDate>Mon, 29 May 2023 12:20:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/opinion/trust-your-users/</guid>
      <description>&lt;p&gt;I was recently introduced to a simple article on system design: &lt;a href=&#34;https://utcc.utoronto.ca/~cks/space/blog/tech/UsersAreRight&#34;&gt;Users
are almost always
right&lt;/a&gt;. In
it, a simple rule is stated:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When the users keep doing it wrong, the users are right and your system
is wrong.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This rule reminded me of the concept of &lt;em&gt;desire paths&lt;/em&gt;: unplanned trails
created by human or animal traffic that usually represent the shortest or
easiest route between two places. Desire paths in an urban setting often
run counter to what a planner might suggest, leading to a natural
conflict between the pedestrian and the planner.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Generating Large Test Files</title>
      <link>https://sookocheff.com/post/linux/generating-large-files/</link>
      <pubDate>Wed, 24 May 2023 09:58:13 +0000</pubDate>
      <guid>https://sookocheff.com/post/linux/generating-large-files/</guid>
      <description>&lt;p&gt;I was recently testing file upload performance, and needed several large
files of different sizes to test with. To make the math easier, it was
helpful if I had files with round numbered sizes like 10MB, 20MB, or
100MB. After searching around for files of the right size, it turns out
the easiest solution is to generate one yourself using the Linux command
line.&lt;/p&gt;
&lt;p&gt;Depending on your needs, you can use two different methods of generating
files using some simple commands.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Generating JSON Web Token Assertions</title>
      <link>https://sookocheff.com/post/api/generating-jwt-assertions/</link>
      <pubDate>Thu, 11 May 2023 14:39:13 +0000</pubDate>
      <guid>https://sookocheff.com/post/api/generating-jwt-assertions/</guid>
      <description>&lt;p&gt;A JWT (JSON Web Token) is a type of security token that is used to
securely transmit information between parties. It is a compact and
self-contained way of representing claims to be transferred between two
parties. Many API providers require you to generate a cryptographically
signed JWT assertion that includes the authorization you are requesting
from the server. If the server accepts the assertions you are claiming in
the JWT, it will respond with an access token granting access to the API.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Tackling Technology Strategy with Portfolio Management</title>
      <link>https://sookocheff.com/post/architecture/tackling-technology-strategy-with-portfolio-management/</link>
      <pubDate>Thu, 27 Apr 2023 08:51:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/tackling-technology-strategy-with-portfolio-management/</guid>
      <description>&lt;p&gt;Application Portfolio Management (APM) draws inspiration from financial
portfolio management, which has been around since at least the 1970s. By
looking at all applications and services in the organization and
analyzing their costs and benefits, you can determine the most effective
way to manage them as part of a larger overall strategy. This allows the
architect or engineering leader to take a more strategic approach to
managing their application portfolio backed by data. Portfolio management
is crucial for creating a holistic view of your team’s technology
landscape and making sure that it aligns with business goals.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Making Sense of Kubernetes Metrics</title>
      <link>https://sookocheff.com/post/kubernetes/making-sense-of-kubernetes-metrics/</link>
      <pubDate>Fri, 24 Mar 2023 08:44:23 -0600</pubDate>
      <guid>https://sookocheff.com/post/kubernetes/making-sense-of-kubernetes-metrics/</guid>
      <description>&lt;p&gt;Shortly after deploying a new Kubernetes cluster, one of the first things
you will likely want to do is collect some metrics and data about how it
operates. There are two projects that are typically used for this, and
since they are named similarly it can be confusing to know which one you
should use and why.&lt;/p&gt;
&lt;p&gt;This post hopes to clear up any confusion between the &lt;a href=&#34;https://github.com/kubernetes-sigs/metrics-server&#34;&gt;Kubernetes Metrics
Server&lt;/a&gt; and
&lt;a href=&#34;https://github.com/kubernetes/kube-state-metrics&#34;&gt;kube-state-metrics&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Project Management for Software Engineers</title>
      <link>https://sookocheff.com/post/engineering-management/project-management-for-software-engineers/</link>
      <pubDate>Wed, 08 Mar 2023 08:01:52 -0600</pubDate>
      <guid>https://sookocheff.com/post/engineering-management/project-management-for-software-engineers/</guid>
      <description>&lt;p&gt;At some point in your career you will be asked to manage a project. This
can be intimidating, it can be scary, but it doesn’t have to be. We can
leverage some time-honoured techniques, and adapt them to the unique
approach required for software projects to deliver on time, on budget,
and with success.&lt;/p&gt;
&lt;p&gt;This article is a collection of techniques I’ve learned for managing
projects over time, that attempts to combine agile best practices with
project management best practices. If you study project management to any
level of depth, it is inevitable that you will come across the Project
Management Institute, or PMI. The PMI is a global professional body that
provides training and certification in project management topics. PMI
provides different certification options, including some for Agile
processes and Scrum.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Increased virtualization performance with the AWS Nitro System</title>
      <link>https://sookocheff.com/post/aws/aws-nitro/</link>
      <pubDate>Wed, 21 Dec 2022 11:59:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/aws/aws-nitro/</guid>
      <description>&lt;p&gt;Amazon’s Elastic Compute Cloud (EC2). EC2 is a web service that provides
resizable, on-demand computing capacity — literally, servers in Amazon’s data
centers — that you use to build and host your software.&lt;/p&gt;
&lt;p&gt;It’s important to understand that EC2 is a &lt;em&gt;virtual&lt;/em&gt; computing environment. In
a virtual environment, there is one physical server with all of the necessary
hardware — CPU, memory, hard disk, network controller and more. This single
physical server can host multiple operating systems and applications through a
&lt;em&gt;hypervisor&lt;/em&gt; that runs directly on top of the physical machine. The following
simplified diagram shows a hypervisor architecture based on the Xen project:
Xen interfaces directly with the hardware, and has a special control domain
(dom0) for interfacing with Xen. Domain 0 is designed to access hardware
directly and manage devices and device drivers. It has the ability to talk to
the hypervisor to instruct it to start and stop guest VMs.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Using Neovim as a Java IDE</title>
      <link>https://sookocheff.com/post/vim/neovim-java-ide/</link>
      <pubDate>Wed, 14 Dec 2022 09:22:09 -0600</pubDate>
      <guid>https://sookocheff.com/post/vim/neovim-java-ide/</guid>
      <description>&lt;p&gt;I first learned Vim in university and, since then, it has been a welcome
companion for the majority of my software engineering career. Working with
Python and Go programs felt natural with Vim and I was always felt productive.
Yet Java was always a different beast. Whenever an opportunity to work with
Java came up, I would inevitably try Vim for a while, but fall back to IntelliJ
and the IdeaVim plugin to take advantage of the rich language features a
full-featured IDE can give you.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Distributed System Models in the Real World</title>
      <link>https://sookocheff.com/post/distributed-systems/distributed-system-models-in-the-real-world/</link>
      <pubDate>Tue, 20 Sep 2022 09:16:09 -0600</pubDate>
      <guid>https://sookocheff.com/post/distributed-systems/distributed-system-models-in-the-real-world/</guid>
      <description>&lt;p&gt;Practical distributed applications are deployed into varied environments
and execute on a variety of different machines linked together over
a variety of communication infrastructure. The physical machines
themselves can differ in the number and speed of processors, the
availability of random access and stable storage, and more. The
communication infrastructure can differ in the available levels of
latency, throughput, and reliability. Because of these differences, it is
more practical to look at distributed algorithms from a higher-level
perspective so that they are applicable to a wide range of environments.
Such algorithms do not depend on the particular details of the hardware or
software on which they are run, and they are not limited to a highly
specialized implementation.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Write-ahead logging and the ARIES crash recovery algorithm</title>
      <link>https://sookocheff.com/post/databases/write-ahead-logging/</link>
      <pubDate>Fri, 26 Aug 2022 05:21:37 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/write-ahead-logging/</guid>
      <description>&lt;p&gt;A central tenet of databases is that any committed data survives a crash
or a failure. Write-ahead logging is a fundamental primitive that ensures
all changes to data are first written safely to stable storage before
being applied. Coupling that with some careful use of sequence numbers and
we can guarantee that changes made to a database can survive system
crashes.&lt;/p&gt;
&lt;h2 id=&#34;motivation&#34;&gt;Motivation&lt;/h2&gt;
&lt;p&gt;Let’s start with a simple transaction &lt;code&gt;T1&lt;/code&gt; that reads object
&lt;code&gt;A&lt;/code&gt;, and updates the value for &lt;code&gt;A&lt;/code&gt; with a write. To simplify matters, &lt;code&gt;A&lt;/code&gt;
is stored on disk as a single page as in Figure 1.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to kill a process that is a using port on macOS</title>
      <link>https://sookocheff.com/post/macos/</link>
      <pubDate>Wed, 29 Jun 2022 09:24:57 +0000</pubDate>
      <guid>https://sookocheff.com/post/macos/</guid>
      <description>&lt;p&gt;Every so often I get stuck with a running process that’s using a specific
port, preventing me from running some new application that uses the
same port. Then I’m left Googling for solutions or rebooting the machine
to make progress. But not any more! I’m recording the solution for my
future self (and of course for you, dear reader).&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;gt; sudo lsof -i :&amp;lt;PortNumber&amp;gt;  &lt;span class=&#34;c1&#34;&gt;# returns list of processes using the port, with PID&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;gt; &lt;span class=&#34;nb&#34;&gt;kill&lt;/span&gt; -9 &amp;lt;PID&amp;gt;  &lt;span class=&#34;c1&#34;&gt;# kill the specific pid&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For example, you can find out what’s running on port number &lt;code&gt;8080&lt;/code&gt; by
running the command:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Progress is a lake, not a line</title>
      <link>https://sookocheff.com/post/opinion/progress-is-a-lake-not-a-line/</link>
      <pubDate>Wed, 01 Jun 2022 12:30:23 +0000</pubDate>
      <guid>https://sookocheff.com/post/opinion/progress-is-a-lake-not-a-line/</guid>
      <description>&lt;p&gt;When people describe progress, they often describe it in terms of a linear
progression taking us from primitive to advanced — an idea or invention
occurs as a singular event, and somewhere further down the line of time
a new idea or invention completely replaces it, relegating the old to the
annals of history.&lt;/p&gt;
&lt;p&gt;This viewpoint is exemplified by traditional worldviews that organize all
beings according to a chain of evolution, sometimes called the “great
chain of being” (or &lt;a href=&#34;https://en.wikipedia.org/wiki/Great_chain_of_being&#34;&gt;scala
naturae&lt;/a&gt;). The chain
of being links God, angels, humans, animals, plants, and minerals in
a hierarchy. All beings on earth, animate and inanimate, could be
organized according to an increasing scale of perfection, from mushrooms
and rocks at the bottom up through lobsters and rabbits, all the way to
human beings and God at the top.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why Systems Work So Well</title>
      <link>https://sookocheff.com/post/systems/why-systems-work-so-well/</link>
      <pubDate>Wed, 11 May 2022 05:48:21 -0600</pubDate>
      <guid>https://sookocheff.com/post/systems/why-systems-work-so-well/</guid>
      <description>&lt;p&gt;In the book “Thinking in Systems”, Donella Meadows dedicates an entire
chapter to explaining why functioning systems seem to work so well. In it,
she recognizes three characteristics: resilience, self-organization, and
hierarchy.&lt;/p&gt;
&lt;h2 id=&#34;resilience&#34;&gt;Resilience&lt;/h2&gt;
&lt;p&gt;We can use the standard definition from the Oxford English dictionary to
describe resilience:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;re·sil·ience /rəˈzilyəns/
noun&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the capacity to recover quickly from difficulties; toughness. &amp;ldquo;the
often remarkable resilience of so many British institutions&amp;rdquo;&lt;/li&gt;
&lt;li&gt;the ability of a substance or object to spring back into shape;
elasticity. &amp;ldquo;nylon is excellent in wearability and resilience&amp;rdquo;&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;According to Donella Meadows this definition can be translated to systems
as the “ability to survive and persist within a variable environment. The
opposite of resilience is brittleness or rigidity.”&lt;/p&gt;</description>
    </item>
    <item>
      <title>Java For The Experienced Beginner</title>
      <link>https://sookocheff.com/post/java/java-for-the-experienced-beginner/</link>
      <pubDate>Wed, 27 Apr 2022 08:31:12 -0400</pubDate>
      <guid>https://sookocheff.com/post/java/java-for-the-experienced-beginner/</guid>
      <description>&lt;p&gt;Java was the first programming language I was taught at University, and
the language I used for the first decade of my career. It continues to be
a reliable companion throughout my software development career.
Unfortunately, not having developed with Java professionally for several
years, I’ve found there are many aspects of the modern Java language that
I’m simply not familiar with. To rectify this, I’ve collected the major
improvements to the language beginning with Java 8, combined with a short
explanation of how they work and how to use them. It assumes you know
Java, but don’t really &lt;em&gt;know&lt;/em&gt; Java. Hopefully, it can take you from
experienced beginner to just plain experienced again.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Behaviour Parameterization</title>
      <link>https://sookocheff.com/post/design-patterns/behaviour-parameterization/</link>
      <pubDate>Tue, 26 Apr 2022 07:37:12 -0400</pubDate>
      <guid>https://sookocheff.com/post/design-patterns/behaviour-parameterization/</guid>
      <description>&lt;p&gt;One of the core features of modern Java is lambda expressions. Introduced
in Java 8, lambdas provide concise syntax allowing the deferred execution
of a block of code. Put a different way, lambdas allow us to pass
behaviour as a method parameter. When the method executes, the lambda
expression is run. This capability is often referred to as &lt;em&gt;behaviour
parameterization&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Behaviour parameterization can be achieved in a number of ways, of which
lambda expressions are usually the most convenient, and they are
definitely the most concise. But what is behaviour parameterization, and
why would we want to use it? To motivate this discussion, let’s work
through a real-world example of filtering a list of items according to
some criteria. More concretely, let’s investigate the problem filtering
a list of students to find the ones with the best grades.&lt;/p&gt;</description>
    </item>
    <item>
      <title>What complex systems can teach us about building software</title>
      <link>https://sookocheff.com/post/systems/what-complex-systems-can-teach-us-about-building-software/</link>
      <pubDate>Wed, 09 Mar 2022 08:10:16 +0000</pubDate>
      <guid>https://sookocheff.com/post/systems/what-complex-systems-can-teach-us-about-building-software/</guid>
      <description>&lt;p&gt;As a software system scales it becomes sufficiently large that the number
of working parts, coupled with the number of working programmers making
changes on it, makes the behaviour of the system extremely difficult to
reason about. This complexity is exacerbated by the transition of many
organizations towards a microservice architecture, as exemplified by the
so-called “death star” architecture, where each point in the circumference
of the circle represents a microservice and the lines between services
represent their interactions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Hybrid Logical Clocks</title>
      <link>https://sookocheff.com/post/time/hybrid-logical-clocks/</link>
      <pubDate>Mon, 24 Jan 2022 06:16:09 -0400</pubDate>
      <guid>https://sookocheff.com/post/time/hybrid-logical-clocks/</guid>
      <description>&lt;p&gt;The theory of distributed systems promoted the use of &lt;a href=&#34;https://sookocheff.com/post/time/lamport-clock/&#34;&gt;logical&lt;/a&gt; &lt;a href=&#34;https://sookocheff.com/post/time/vector-clocks/&#34;&gt;clocks&lt;/a&gt; by introducing the idea of
causality tracking as an abstraction for reasoning about concurrency
between events in the system. In practice, a lot of systems continue to
operate using &lt;a href=&#34;https://sookocheff.com/post/time/how-does-ntp-work/&#34;&gt;physical&lt;/a&gt; &lt;a href=&#34;https://sookocheff.com/post/time/truetime/&#34;&gt;time&lt;/a&gt;, which presents
difficulties due to clock synchronization drift. In an effort to bridge
the gap between physical and logical time, &lt;a href=&#34;https://sookocheff.com/post/time/hybrid-time/&#34;&gt;HybridTime&lt;/a&gt; combines both logical and physical
times in one system.&lt;/p&gt;
&lt;p&gt;Hybrid Logical Clocks (HLC) are extensions of the previous causality and time
keeping systems that capture the causality relationship like logical
clocks, but that can also substituted for physical clocks by maintaining
its logical value always close to NTP. With these semantics, HLC can be
used in lieu of a physical clock source like NTP for database reads, and
it can simultaneously be used as a logical clock to identify consistent
global snapshots.&lt;/p&gt;</description>
    </item>
    <item>
      <title>HybridTime</title>
      <link>https://sookocheff.com/post/time/hybrid-time/</link>
      <pubDate>Tue, 11 Jan 2022 06:16:09 -0400</pubDate>
      <guid>https://sookocheff.com/post/time/hybrid-time/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://users.ece.utexas.edu/~garg/pdslab/david/hybrid-time-tech-report-01.pdf&#34;&gt;HybridTime&lt;/a&gt;
introduces a hybrid between physical and logical clocks that can be used
to implement globally consistent database snapshots. HybridTime is one
implementation of the general concept of &lt;a href=&#34;https://martinfowler.com/articles/patterns-of-distributed-systems/hybrid-clock.html&#34;&gt;Hybrid Logical
Clocks&lt;/a&gt;
that combine the logical clock semantics of &lt;a href=&#34;https://sookocheff.com/post/time/lamport-clock/&#34;&gt;Lamport&lt;/a&gt; and &lt;a href=&#34;https://sookocheff.com/post/time/vector-clocks/&#34;&gt;Vector&lt;/a&gt; clocks with a physical
representation of time such as Spanner’s &lt;a href=&#34;https://sookocheff.com/post/time/truetime/&#34;&gt;TrueTime&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;HybridTime follows similar update semantics as Lamport and Vector Clocks,
where each node in the system updates their internal clock in response to
events received. It differs in that HybridTime values are not purely
logical — they include a physical time component that allows values to be
associated with a physical point-in-time.&lt;/p&gt;</description>
    </item>
    <item>
      <title>TrueTime</title>
      <link>https://sookocheff.com/post/time/truetime/</link>
      <pubDate>Thu, 23 Dec 2021 06:16:09 -0400</pubDate>
      <guid>https://sookocheff.com/post/time/truetime/</guid>
      <description>&lt;p&gt;TrueTime is Google’s solution to providing to globally consistent
timestamps to determine ordering of events. Originally developed to
support the Spanner distributed database, TrueTime is a clock
implementation that depends on two key factors: well engineered and
accurate GPS and atomic clocks and the representation of time as an
interval of uncertainty.&lt;/p&gt;
&lt;h2 id=&#34;representing-truetime&#34;&gt;Representing TrueTime&lt;/h2&gt;
&lt;p&gt;TrueTime explicitly represents each timestamp an interval that includes
bounded time uncertainty. TrueTime represents time as an interval of the
type &lt;code&gt;TTinterval&lt;/code&gt;, which includes two timestamps for the beginning and the
end of the interval. These timestamps have type &lt;code&gt;TTstamp&lt;/code&gt;. With this in
mind, the TrueTime API provides the following methods reproduced from
&lt;a href=&#34;https://research.google/pubs/pub39966/&#34;&gt;Spanner: Google’s Globally-Distributed
Database&lt;/a&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Vector Clocks</title>
      <link>https://sookocheff.com/post/time/vector-clocks/</link>
      <pubDate>Mon, 20 Dec 2021 06:16:09 -0400</pubDate>
      <guid>https://sookocheff.com/post/time/vector-clocks/</guid>
      <description>&lt;p&gt;Vector clocks are an extension of &lt;a href=&#34;https://sookocheff.com/post/time/lamport-clock/&#34;&gt;Lamport Clocks&lt;/a&gt; designed to determine all
correct orderings of events in a distributed system. Whereas Lamport
Clocks yield one of the many possible event orderings, this does not for
certain classes of problems that require knowledge of global program state
such as reversing the order of execution to recover from errors or
rollback. In such cases, it is more useful to have access to the entire
set of orderings that are causally consistent at any moment in time.
Vector clocks are designed for exactly such cases.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Lamport Clocks</title>
      <link>https://sookocheff.com/post/time/lamport-clock/</link>
      <pubDate>Wed, 08 Dec 2021 06:16:09 -0400</pubDate>
      <guid>https://sookocheff.com/post/time/lamport-clock/</guid>
      <description>&lt;p&gt;Computers generally track the current time using a quartz crystal that
oscillates at a known frequency. This frequency is used to advance the
local clock at pre-defined intervals. Quartz oscillates with enough
stability that it can be used to maintain time within a few milliseconds
of accuracy per day. Over time however, these imperfections can
accumulate, making the clock inaccurate. To fix these inaccuracies,
computers typically run a background process like &lt;a href=&#34;https://sookocheff.com/post/time/how-does-ntp-work/&#34;&gt;NTP&lt;/a&gt; to synchronize the local clock
with servers that are known to be accurate.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Does NTP Work?</title>
      <link>https://sookocheff.com/post/time/how-does-ntp-work/</link>
      <pubDate>Tue, 23 Nov 2021 06:16:09 -0400</pubDate>
      <guid>https://sookocheff.com/post/time/how-does-ntp-work/</guid>
      <description>&lt;p&gt;The Network Time Protocol (NTP) is a system for synchronizing the clocks
of hosts and clients across the Internet. NTP is a protocol intended to
synchronize all computers participating in the network to within a few
milliseconds of Coordinated Universal Time (UTC). The core of the protocol
is NTP’s clock discipline algorithm that adjusts the local computer’s
clock time and tick frequency in response to an external source — such as
another trusted NTP server, a radio or satellite receiver, or a telephone
modem. A core problem in NTP is establishing the trust and accuracy of
nodes in the NTP network. This is done through a combination of selection
and filtering algorithms to choose from the most reliable and accurate
peer in the synchronization network.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Local Kubernetes Development with microk8s</title>
      <link>https://sookocheff.com/post/kubernetes/local-kubernetes-development-with-microk8s/</link>
      <pubDate>Fri, 24 Sep 2021 09:44:23 -0400</pubDate>
      <guid>https://sookocheff.com/post/kubernetes/local-kubernetes-development-with-microk8s/</guid>
      <description>&lt;p&gt;Still &lt;a href=&#34;https://sookocheff.com/post/kubernetes/local-kubernetes-development-with-tilt/&#34;&gt;in&lt;/a&gt;
&lt;a href=&#34;https://sookocheff.com/post/kubernetes/local-kubernetes-development-with-kind/&#34;&gt;search&lt;/a&gt; of
a Kubernetes development environment I can run on my development machine
that somewhat replicates, I was recently introduced to both the
&lt;a href=&#34;https://multipass.run/&#34;&gt;multipass&lt;/a&gt; and &lt;a href=&#34;https://microk8s.io/&#34;&gt;microk8s&lt;/a&gt;
projects from Canonical.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://multipass.run/&#34;&gt;multipass&lt;/a&gt; is a prerequisite for microk8s, so
let’s start there. With multipass, you can easily launch and run Ubuntu
virtual machines with a single command.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;❯ multipass launch --name foo
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Launched: foo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With a virtual machine in hand, you can run execute arbitrary commands on
the machine using the &lt;code&gt;exec&lt;/code&gt; subcommand.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why Foxes Make Better Decisions Than Hedgehogs</title>
      <link>https://sookocheff.com/post/engineering-management/why-foxes-make-better-decisions-than-hedgehogs/</link>
      <pubDate>Thu, 15 Jul 2021 08:01:52 -0600</pubDate>
      <guid>https://sookocheff.com/post/engineering-management/why-foxes-make-better-decisions-than-hedgehogs/</guid>
      <description>&lt;p&gt;The ancient Greek poet Archilochus wrote that “the fox knows many things,
but the hedgehog knows one big thing.” In social psychology, these terms
have been used as a shorthand for describing two cognitive styles: foxes,
who are comfortable with nuance, can live with contradictions, and have
different strategies for solving different problems, and hedgehogs, who
focus on the big picture, reduce every problem to one organizing
principle, and solve problems through that singular lens.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Connecting Technology to the Needs of the Business</title>
      <link>https://sookocheff.com/post/architecture/connecting-technology-to-the-needs-of-the-business/</link>
      <pubDate>Mon, 21 Jun 2021 06:59:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/connecting-technology-to-the-needs-of-the-business/</guid>
      <description>&lt;p&gt;All healthy technology discussions should begin with business goals and
use those goals as a reasonable set of guidelines to focus technology
investment decisions. These business goals are best articulated from
a deep understanding of what the company, the product team, or the
marketing team want to accomplish.&lt;/p&gt;
&lt;p&gt;In a business-first model, technology is forced to balance the desires for
technical effectiveness and efficiency with the operational needs of the
business. This balance can be difficult to achieve if you’ve ended up in
a leadership position from a technology background — you are used to
solving problems by writing code and it becomes difficult to think of
other ways to solve them!&lt;/p&gt;</description>
    </item>
    <item>
      <title>The False Dichotomy of Design-First and Code-First API Development</title>
      <link>https://sookocheff.com/post/api/the-false-dichotomoy-of-design-first-and-code-first-api-development/</link>
      <pubDate>Tue, 08 Jun 2021 05:46:53 +0000</pubDate>
      <guid>https://sookocheff.com/post/api/the-false-dichotomoy-of-design-first-and-code-first-api-development/</guid>
      <description>&lt;p&gt;In creating a development workflow for releasing HTTP+JSON APIs, many
teams settle on the API description and documentation standard OpenAPI.
A natural conversation that takes place after settling on OpenAPI is
whether or not you should develop your API using a “design-first” method
or a “code-first” method. I believe that narrowing the discussion to these
two extremes overly simplifies the discussion. Instead, I prefer to talk
about API development as a continuum of development process that revolve
around the prominence of the API description document in the process.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Most Important Criteria for Choosing a Programming Language</title>
      <link>https://sookocheff.com/post/engineering-management/the-most-important-criteria-for-choosing-a-programming-language/</link>
      <pubDate>Thu, 20 May 2021 08:01:52 -0600</pubDate>
      <guid>https://sookocheff.com/post/engineering-management/the-most-important-criteria-for-choosing-a-programming-language/</guid>
      <description>&lt;p&gt;One of the recurring themes of any technology discussion is programming
language. It doesn’t take much effort to find blog posts with dramatic
headlines (and even more dramatic comments) about how shipping a new
project with Haskell or Clojure or Elm improved someones job, marriage,
and life. These success stories are posted by raving fans that have
nothing but the best to say about their language of choice. A common
thread running through these posts is that they are typically tied to
building out new, greenfield projects. I can’t help but wonder. After the
honeymoon of building a new project with a new programming language, what
happens next? Is it all bubble gum and roses?&lt;/p&gt;</description>
    </item>
    <item>
      <title>Augmenting Spring Data REST with Additional Endpoints</title>
      <link>https://sookocheff.com/post/java/augmenting-spring-data-rest-with-additional-endpoints/</link>
      <pubDate>Wed, 19 May 2021 08:01:52 -0600</pubDate>
      <guid>https://sookocheff.com/post/java/augmenting-spring-data-rest-with-additional-endpoints/</guid>
      <description>&lt;p&gt;Spring Data REST combines the features of &lt;a href=&#34;https://spring.io/projects/spring-data&#34;&gt;Spring
Data&lt;/a&gt; with &lt;a href=&#34;https://spring.io/projects/spring-hateoas&#34;&gt;Spring
HATEOAS&lt;/a&gt; to make it easy to
build hypermedia-driven REST APIs on top of Spring Data repositories. The
basic functionality provided out of the box creates and exposes simple
REST endpoints for performing CRUD operations on Spring Data repositories.
For a lot of use cases, this is entirely enough functionality to meet your
needs. In other cases, you need to extend the REST API to include
additional functionality that isn’t provided by Spring Data REST and it
can be difficult to determine exactly how to do this. In this blog post,
I show you how to augment a Spring Data REST API with additional endpoints
to turn a basic CRUD API into a full featured web service.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Making Modular Monoliths Work</title>
      <link>https://sookocheff.com/post/architecture/making-modular-monoliths-work/</link>
      <pubDate>Thu, 18 Feb 2021 09:40:16 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/making-modular-monoliths-work/</guid>
      <description>&lt;p&gt;Microservices have become part of the software engineering cultural
zeitgeist to the extent that alternative approaches to architecture and
development are treated as somehow inferior. Given the challenges that
running microservices present, I usually recommend beginning development
of new projects and systems as a single deployable unit — the &lt;em&gt;monolith&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Sam Newman, in the book “Building Microservices”, agrees with this
approach. He recommends leveraging microservices only if you can become
convinced of the benefits for your system, not as a default for every
project.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Unpacking the eight fallacies of distributed computing</title>
      <link>https://sookocheff.com/post/distributed-systems/unpacking-the-eight-fallacies-of-distributed-computing/</link>
      <pubDate>Thu, 11 Feb 2021 09:16:09 -0600</pubDate>
      <guid>https://sookocheff.com/post/distributed-systems/unpacking-the-eight-fallacies-of-distributed-computing/</guid>
      <description>&lt;p&gt;When building and running a system deployed as a monolith, we are able to
make a certain set of assumptions about the behaviour of the overall
application. One of the biggest assumptions we make is that the memory
space for the application all resides on the same machine. With this
model, function and library calls can assume that their view of the data
structures for the application are accurate, and that you can retrieve or
mutate that data immediately and deterministically (leaving the thornier
issues of multi-threaded applications aside for a minute). These
assumptions allow teams of programmers to work effectively and efficiently
across multiple packages, libraries, classes and functions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Handling the rudder as an organization grows</title>
      <link>https://sookocheff.com/post/opinion/steering-a-boat/</link>
      <pubDate>Fri, 15 Jan 2021 05:03:32 +0000</pubDate>
      <guid>https://sookocheff.com/post/opinion/steering-a-boat/</guid>
      <description>&lt;p&gt;In a shopping cart, the swivel wheels of the cart are set in the front,
and the fixed wheels are set in the back.&lt;/p&gt;
&lt;p&gt;Now picture yourself pushing a shopping cart backwards. Almost naturally,
you swivel the cart to move the front end to one side or the other before
beginning to push the cart. Now picture yourself pushing a shopping cart
backwards, &lt;em&gt;on an ice rink&lt;/em&gt;. Here, the cart keeps sliding around even
after you’ve stopped pushing it. Instead of going straight from one end of
the rink to the other, the cart makes giant S-shaped turns.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Cathedral, The Bazaar, and the API Marketplace</title>
      <link>https://sookocheff.com/post/api/the-cathedral-the-bazaar-and-the-api-marketplace/</link>
      <pubDate>Fri, 11 Dec 2020 11:16:53 +0000</pubDate>
      <guid>https://sookocheff.com/post/api/the-cathedral-the-bazaar-and-the-api-marketplace/</guid>
      <description>&lt;p&gt;In &lt;a href=&#34;http://www.catb.org/~esr/writings/cathedral-bazaar/cathedral-bazaar/&#34;&gt;The Cathedral and the
Bazaar&lt;/a&gt;,
Eric Raymond recounts the early years of Linux. Specifically questioning
how the “part-time hacking of several thousands of developers scattered
all over the planet” could create perhaps the most complex, functioning
application in history. How could a “babbling bazaar of differing agendas
and approaches” coalesce into a coherent and stable system without some
form of centralized planning?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The fact that this bazaar style seemed to work, and work well, came as
a distinct shock. As I learned my way around, I worked hard not just at
individual projects, but also at trying to understand why the Linux
world not only didn&amp;rsquo;t fly apart in confusion but seemed to go from
strength to strength at a speed barely imaginable to cathedral-builders.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Marrying RESTful HTTP with Asynchronous and Event-Driven Services</title>
      <link>https://sookocheff.com/post/api/marrying-restful-http-with-asynchronous-design/</link>
      <pubDate>Tue, 24 Nov 2020 12:16:18 +0000</pubDate>
      <guid>https://sookocheff.com/post/api/marrying-restful-http-with-asynchronous-design/</guid>
      <description>&lt;p&gt;Many organizations have multiple applications that are being built
independently as a microservices-based platform. By its nature,
a microservice platform is a distributed system running on multiple
processes or services, across multiple servers or hosts. Building
a successful platform on top of microservices requires integrating these
disparate services and systems to produce a unified set of functionality.&lt;/p&gt;
&lt;p&gt;It is naïve to think that we can only choose one communication style to
solve all problems; if integration needs were always the same, there would
be only one style and we would all be happy with it. In reality, a single
service can can communicate using many different styles, each one
targeting a different scenario and goals. This challenge is what brings me
to the topic of this blog post: when and why do we use different
communication standards?&lt;/p&gt;</description>
    </item>
    <item>
      <title>Running a Dapr Application on Kubernetes</title>
      <link>https://sookocheff.com/post/dapr/running-a-dapr-application-on-kubernetes/</link>
      <pubDate>Fri, 23 Oct 2020 10:09:59 -0600</pubDate>
      <guid>https://sookocheff.com/post/dapr/running-a-dapr-application-on-kubernetes/</guid>
      <description>&lt;p&gt;With so many people running microservice workloads, it is inevitable that
organizations keep bumping into the same set of problems: state
management, resiliency, event-handling, and more. Dapr exists to help
codify the best practices for building microservice applications into
building blocks that enable you to build portable
applications with the language and framework of your choice. Each building
block is completely independent and you can use one, some, or all of them
in your application to solve common microservice problems.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Local Kubernetes Development with Tilt</title>
      <link>https://sookocheff.com/post/kubernetes/local-kubernetes-development-with-tilt/</link>
      <pubDate>Mon, 05 Oct 2020 08:44:23 -0600</pubDate>
      <guid>https://sookocheff.com/post/kubernetes/local-kubernetes-development-with-tilt/</guid>
      <description>&lt;p&gt;In my &lt;a href=&#34;https://sookocheff.com/post/kubernetes/local-kubernetes-development-with-tilt/&#34;&gt;last post&lt;/a&gt;
I detailed how to setup a local Kubernetes development cluster using
&lt;a href=&#34;https://kind.sigs.k8s.io/&#34;&gt;kind&lt;/a&gt;. This post shows how to leverage this
new cluster when developing a system or application that relies on
multiple microservices using &lt;a href=&#34;https://tilt.dev/&#34;&gt;tilt&lt;/a&gt;. If you haven’t
setup your local environment with kind yet, refer back to my &lt;a href=&#34;https://sookocheff.com/post/kubernetes/local-kubernetes-development-with-tilt/&#34;&gt;last post&lt;/a&gt;
before continuing on.&lt;/p&gt;
&lt;h2 id=&#34;installing-tilt&#34;&gt;Installing Tilt&lt;/h2&gt;
&lt;p&gt;You can install the &lt;code&gt;tilt&lt;/code&gt; binary using Homebrew or through curl and an installation
script:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Local Kubernetes Development with kind</title>
      <link>https://sookocheff.com/post/kubernetes/local-kubernetes-development-with-kind/</link>
      <pubDate>Mon, 28 Sep 2020 11:44:23 -0600</pubDate>
      <guid>https://sookocheff.com/post/kubernetes/local-kubernetes-development-with-kind/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://kind.sigs.k8s.io/&#34;&gt;kind&lt;/a&gt; is a tool built for running local
Kubernetes clusters using Docker containers as nodes. kind was primarily
designed for testing Kubernetes itself, but it is actually quite useful
for creating a Kubernetes environment for local development, QA, or CI/CD.
This blog post shows you how to setup a kind-based environment for local
development that can mimic a production Kubernetes environment.&lt;/p&gt;
&lt;p&gt;A fully functioning environment using kind includes a few different
components. For our purposes, we will install the following list of
software.&lt;/p&gt;</description>
    </item>
    <item>
      <title>There and Back Again: The Unexpected Journey of a Request</title>
      <link>https://sookocheff.com/post/networking/there-and-back-again/</link>
      <pubDate>Tue, 18 Aug 2020 06:54:45 +0000</pubDate>
      <guid>https://sookocheff.com/post/networking/there-and-back-again/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;It&amp;rsquo;s a dangerous business, Frodo, going out your door.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Kubernetes and public cloud infrastructure introduce a few layers of abstraction
between users and our services. This article unravels some of those layers to
help understand what, exactly, happens between the time a user makes a request
to a Kubernetes service running in AWS and when the user receives a response.
It&amp;rsquo;s helpful to start by framing a request in terms of the network boundaries
involved, so let&amp;rsquo;s start there.&lt;/p&gt;</description>
    </item>
    <item>
      <title>VoltDB</title>
      <link>https://sookocheff.com/post/databases/getting-to-know-voltdb/</link>
      <pubDate>Wed, 03 Jun 2020 06:00:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/getting-to-know-voltdb/</guid>
      <description>&lt;p&gt;VoltDB is an in-memory database borne out of the H-Store research project
spearheaded by Michael Stonebraker. Within that project, Michael started with
the premise of building a fully transactional database with the best possible
performance by using insights gathered from an &lt;a href=&#34;https://sookocheff.com/post/databases/oltp-through-the-looking-glass/&#34;&gt;in-depth study&lt;/a&gt; on database
performance that completely removed disk access — the primary limiting
factor on database performance. By removing disk access completely, we end up
with a completely in-memory database where we can make additional optimizations
like removing write-ahead logging, buffer management, and locks and latches.
This effort resulted in the research database
&lt;a href=&#34;https://hstore.cs.brown.edu/&#34;&gt;H-Store&lt;/a&gt; which was commercialized as the
in-memory database &lt;a href=&#34;https://www.voltdb.com/&#34;&gt;VoltDB&lt;/a&gt;. This article takes a
deeper dive into VoltDB to understand how it works and where you may benefit
from this approach.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Understanding Spring&#39;s Environment Abstraction</title>
      <link>https://sookocheff.com/post/java/understanding-springs-environment-abstraction/</link>
      <pubDate>Wed, 27 May 2020 09:57:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/java/understanding-springs-environment-abstraction/</guid>
      <description>&lt;p&gt;When working with Spring Boot, some auto-configuration can happen seemingly by
magic. For example, in a traditional Spring application with Java-based
configuration, you might configure an H2 database using the following block of
code to set the type of the database and run some scripts to initialize it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@Bean&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DataSource&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;dataSource&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EmbeddedDataSourceBuilder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;setType&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;H2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;addScript&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;taco_schema.sql&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;addScripts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;user_data.sql&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;ingredient_data.sql&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;build&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With Spring Boot, you can remove this entire block of code and use
auto-configuration. If the H2 dependency is available in the classpath, Spring
Boot will automatically create the &lt;code&gt;DataSource&lt;/code&gt; and add it as a &lt;code&gt;Bean&lt;/code&gt; to
Spring&amp;rsquo;s application context and apply SQL scripts as long as they are named
&lt;code&gt;schema.sql&lt;/code&gt; or &lt;code&gt;data.sql&lt;/code&gt;. Spring Boot does this auth-configuration by
leveraging the Spring environment that collects the set of properties available
to a Java application and uses those properties to configure beans in Spring&amp;rsquo;s
application context. The following figure from &lt;a href=&#34;https://www.manning.com/books/spring-in-action-fifth-edition&#34;&gt;Spring in
Action&lt;/a&gt; shows how
the Spring environment is generated by some of the available configuration
property sources available in a typical Java application.&lt;/p&gt;</description>
    </item>
    <item>
      <title>What is the OCaml toplevel?</title>
      <link>https://sookocheff.com/post/ocaml/ocaml-basics/</link>
      <pubDate>Fri, 22 May 2020 08:13:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/ocaml/ocaml-basics/</guid>
      <description>&lt;p&gt;Many OCaml guides and tutorials refer to the OCaml toplevel, but what exactly is
this thing? In short, the toplevel is OCaml&amp;rsquo;s Read-Eval-Print-Loop (repl)
allowing interative use of the OCaml system. You can consider the toplevel an
alternative to compiling OCaml into an executable. In this mode, the OCaml
system is configured to repeatedly read phrases from input, typecheck, compile,
and evaluate them, then print the inferred type and result value.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Building a Modern Java Web App with Spring Boot</title>
      <link>https://sookocheff.com/post/java/building-a-modern-java-web-app-with-spring-boot/</link>
      <pubDate>Wed, 20 May 2020 09:13:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/java/building-a-modern-java-web-app-with-spring-boot/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m a &lt;a href=&#34;https://sookocheff.com/post/java/why-java/&#34;&gt;fan of Java&lt;/a&gt;. If you haven&amp;rsquo;t
given it a chance in a while, you may not have noticed that, Java has quietly
been adopting some of the best practices that make dynamic and functional
languages so appealing, without sacrificing the many hundred person-years of
effort that have made Java and the JVM a world-class development environment.
Java is still one the world’s &lt;a href=&#34;https://www.tiobe.com/tiobe-index/&#34;&gt;most popular programming
languages&lt;/a&gt; with roughly 9 million
programmers using Java. It doesn’t make sense to ignore all of that history and
development effort because of a niggling feeling that Java is a little too
verbose, or that XML is so last year.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Inversion of Control, Dependency Injection, and the Spring IoC Container</title>
      <link>https://sookocheff.com/post/java/inversion-of-control-and-the-spring-ioc-container/</link>
      <pubDate>Thu, 14 May 2020 09:13:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/java/inversion-of-control-and-the-spring-ioc-container/</guid>
      <description>&lt;p&gt;Inversion of Control (IoC), also known as Dependency Injection (DI), allows an
object to define their dependencies as constructor arguments (strictly speaking,
you can set these dependencies as properties, but the examples I will use today
are constructor-based). This is the inverse of the object itself controlling the
instantiation or location of its dependencies, hence the name &lt;em&gt;Inversion of Control&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s look at an example from
&lt;a href=&#34;https://stackoverflow.com/questions/3058/what-is-inversion-of-control&#34;&gt;Stackoverflow&lt;/a&gt;
using a text editor with a spell checking component:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Starting a new OCaml project using Dune and Visual Studio Code</title>
      <link>https://sookocheff.com/post/ocaml/starting-a-new-ocaml-project-using-dune-and-visual-studio-code/</link>
      <pubDate>Tue, 12 May 2020 11:13:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/ocaml/starting-a-new-ocaml-project-using-dune-and-visual-studio-code/</guid>
      <description>&lt;p&gt;After recently setting up a new machine and going through the exercise of
setting up a development environment for the nth time, I was frustrated by
having to install and configure all of my plugins and dependencies to support
auto-completion, syntax highlighting, and the other niceties I&amp;rsquo;ve come to enjoy
with Vim. Looking for an alternative, I was drawn to Visual Studio Code (VS
Code) with the &lt;a href=&#34;https://github.com/VSCodeVim/Vim&#34;&gt;VSCodeVim&lt;/a&gt; extension.
Combining Vim key-bindings with Code&amp;rsquo;s excellent extension marketplace, I was
able to recreate and in some cases improve the development environment I enjoyed
as a Vim user in VS Code. This blog post continues that discovery by setting up a
brand new OCaml project and development environment in VS Code.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Tour Through OCaml with Project Euler</title>
      <link>https://sookocheff.com/post/ocaml/a-tour-through-ocaml-with-project-euler/</link>
      <pubDate>Fri, 08 May 2020 09:13:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/ocaml/a-tour-through-ocaml-with-project-euler/</guid>
      <description>&lt;p&gt;This post covers some of the major features of OCaml while solving Problem 1
from &lt;a href=&#34;https://projecteuler.net/archives&#34;&gt;Project Euler&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&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.&lt;/p&gt;
&lt;p&gt;Find the sum of all the multiples of 3 or 5 below 1000.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let&amp;rsquo;s get started on this problem by looking at the math facilities provided by
OCaml. Start a new interactive session using &lt;code&gt;utop&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Getting Started with opam, the OCaml Package Manager</title>
      <link>https://sookocheff.com/post/ocaml/getting-started-with-opam/</link>
      <pubDate>Mon, 04 May 2020 11:13:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/ocaml/getting-started-with-opam/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://opam.ocaml.org/&#34;&gt;opam&lt;/a&gt; — the OCaml Package Manager — is the
tool for installing OCaml and any OCaml tools and libraries. This blog post
shows us how to set-up opam to install the OCaml compiler and development tools
to support your workflow.&lt;/p&gt;
&lt;h2 id=&#34;working-with-windows&#34;&gt;Working with Windows&lt;/h2&gt;
&lt;p&gt;The OCaml tools are typically well supported on Linux, with macOS ports
available of most binaries. If you are on a Windows, the best supported
environment is the Windows Subsystem for Linux.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The OCaml Compiler Pipeline</title>
      <link>https://sookocheff.com/post/ocaml/the-ocaml-compiler-pipeline/</link>
      <pubDate>Fri, 01 May 2020 11:13:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/ocaml/the-ocaml-compiler-pipeline/</guid>
      <description>&lt;p&gt;I was first introduced to ML through the Coursera &lt;a href=&#34;https://www.coursera.org/learn/programming-languages&#34;&gt;Programming Languages
course&lt;/a&gt;. After the initial
learning curve, I was impressed by the power of the type system and the
flexibility of pattern matching. I&amp;rsquo;ve been wanting to resume &lt;a href=&#34;https://sookocheff.com/post/fp/a-functional-learning-plan/&#34;&gt;my education in
functional programming&lt;/a&gt;, and am picking up OCaml for
a &lt;a href=&#34;https://sookocheff.com/post/dsm/improving-software-architecture-using-design-structure-matrix/&#34;&gt;personal project I&amp;rsquo;m working on&lt;/a&gt;.
Diving into the OCaml ecoystem, I was drawn to Reason, a new syntax for OCaml,
and BuckleScript a compiler that integrates OCaml with the JavaScript ecosystem.
The relationship between &lt;a href=&#34;https://reasonml.github.io/&#34;&gt;Reason&lt;/a&gt;,
&lt;a href=&#34;https://bucklescript.github.io/&#34;&gt;BuckleScript&lt;/a&gt;, and &lt;a href=&#34;https://ocaml.org/&#34;&gt;OCaml&lt;/a&gt;
can difficult to understand, leading to this blog post about the OCaml compiler
pipeline that highlights the intersection between OCaml and BuckleScript.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Above-the-line and below-the-line</title>
      <link>https://sookocheff.com/post/systems/above-the-line-below-the-line/</link>
      <pubDate>Wed, 22 Apr 2020 05:48:21 -0600</pubDate>
      <guid>https://sookocheff.com/post/systems/above-the-line-below-the-line/</guid>
      <description>&lt;p&gt;Engineering, for much of the twentieth century, was mainly about artifacts and
inventions. Now, it&amp;rsquo;s increasingly about complex systems. As the airplane taxis
to the gate, you access the Internet and check email with your PDA, linking the
communication and transportation systems. At home, you recharge your plug-in
hybrid vehicle, linking transportation to the electricity grid. At work, you
develop code, commit it to a repository, run test cases, deploy to production,
and monitor the result. Today&amp;rsquo;s large-scale, highly complex systems converge,
interact, and depend on each other in ways engineers of old could barely have
imagined. As scale, scope, and complexity increase, engineers consider technical
and social issues together in a highly integrated way as they design flexible,
adaptable, robust systems that can be easily modified and reconfigured to
satisfy changing requirements and new technological opportunities.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Does DNS Work?</title>
      <link>https://sookocheff.com/post/networking/how-does-dns-work/</link>
      <pubDate>Thu, 16 Apr 2020 05:59:12 +0000</pubDate>
      <guid>https://sookocheff.com/post/networking/how-does-dns-work/</guid>
      <description>&lt;p&gt;Before the Internet became a global network connecting millions of devices, it
was a simple research experiment connecting a handful of institutions. In the
beginning, the number of unique internet addresses could be measured in the
tens. As the network expanded that number quickly grew into the hundreds and
thousands and it became difficult to remember and type in IP addresses for each
of these hosts.&lt;/p&gt;
&lt;p&gt;To manage the growing number of network hosts, a simple text file, called
&lt;code&gt;HOSTS.txt&lt;/code&gt; recorded each host and their IP address. To add your name to the
hosts file, you needed to send an e-mail describing the changes you wanted to
apply. The authority for the &lt;code&gt;HOSTS.txt&lt;/code&gt; file would apply these changes once or
twice a week and anyone who wanted to grab the updated list would periodically
FTP to the canonical source, grab the latest file, and update their own list of
hosts. Naturally, as this small network expanded into, and was eventually
replaced by, the Internet, this solution became untenable – there were just too
many hosts to keep track of, keep consistent, and to serve from a single
canonical file using FTP and manual updates. &lt;code&gt;HOSTS.txt&lt;/code&gt; did not scale.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Building Learning Communities</title>
      <link>https://sookocheff.com/post/architecture/building-learning-communities/</link>
      <pubDate>Tue, 24 Mar 2020 11:59:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/building-learning-communities/</guid>
      <description>&lt;p&gt;Leading software companies have discovered that developing capable technology
is not enough to guarantee long-term success. To stay relevant, software
leaders need to develop and support the repeatable systems necessary to
develop and sustain knowledge and expertise. Many organizations have taken
inspiration from
&lt;a href=&#34;https://labs.spotify.com/2014/03/27/spotify-engineering-culture-part-1/&#34;&gt;Spotify&amp;rsquo;s&lt;/a&gt;
culture and adopted the concept of a guild or community of practice to
connect engineers throughout the organization and steer them towards common
goals. As organizations adopt this model, what is often missing is a clear
understanding of the purpose of communities of practice and a repeatable
process for developing the communities to their fullest potential. This post
provides some guidance based on our experience developing a community of
practice at &lt;a href=&#34;https://www.workiva.com/&#34;&gt;Workiva&lt;/a&gt;, it also includes some best
practices from the book &lt;a href=&#34;https://hbswk.hbs.edu/archive/cultivating-communities-of-practice-a-guide-to-managing-knowledge-seven-principles-for-cultivating-communities-of-practice&#34;&gt;Cultivating Communities of Practice&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Optimizing Processes Using a Design Structure Matrix</title>
      <link>https://sookocheff.com/post/dsm/optimizing-processes-with-a-dsm/</link>
      <pubDate>Thu, 27 Feb 2020 05:48:21 -0600</pubDate>
      <guid>https://sookocheff.com/post/dsm/optimizing-processes-with-a-dsm/</guid>
      <description>&lt;p&gt;Complex processes may require collaboration and coordination of many
components. We can model such processes using a &lt;a href=&#34;https://dsmweb.org/&#34;&gt;Design Structure
Matrix&lt;/a&gt; to represent information flow among the
components, and then optimize the process to avoid rework and downtime.&lt;/p&gt;
&lt;p&gt;As a simplified example, consider a project with only two tasks: “A” and
“B”, and a directed graph representing this system where a vertex
represents a task and an edge represents the flow of information between
tasks. Depending on the process being modeled, these two vertices can be
arranged in one of three different configurations.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Interdependence and Self-Reliance</title>
      <link>https://sookocheff.com/post/architecture/interdependence-and-self-reliance/</link>
      <pubDate>Mon, 27 Jan 2020 09:40:16 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/interdependence-and-self-reliance/</guid>
      <description>&lt;p&gt;After graduating from university my (future) wife and I travelled
and worked in Kenya as part of the &lt;a href=&#34;https://thecommonwealth.org/commonwealth-learning&#34;&gt;Commonwealth of
Learning&lt;/a&gt; — an
intergovernmental agency dedicated to open learning and distance
education. As fortune would have it, my brother had an internship
in the neighbouring country of Tanzania during the same time period, and
we were able to meet for a few days to enjoy the East African coast in the
city of Mombasa.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Improving Software Architecture Using a Design Structure Matrix</title>
      <link>https://sookocheff.com/post/dsm/improving-software-architecture-using-design-structure-matrix/</link>
      <pubDate>Mon, 20 Jan 2020 05:48:21 -0600</pubDate>
      <guid>https://sookocheff.com/post/dsm/improving-software-architecture-using-design-structure-matrix/</guid>
      <description>&lt;p&gt;To meet the challenges of scaling systems in size, scope, and complexity,
it is useful to look at new approaches and theories to analyze, design,
deploy, and manage these systems. A &lt;a href=&#34;https://dsmweb.org/&#34;&gt;Design Structure Matrix
(DSM)&lt;/a&gt; is an approach that supports the management of
complexity by focusing attention on the elements of complex systems and
how they relate to each other. DSM‐based techniques have proven to be very
valuable in understanding, designing, and optimizing product,
organization, and process architectures. This article explores in more
depth how we can use the techniques developed by the design structure
matrix community to improve software architecture.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Using Little’s Law to Measure System Performance</title>
      <link>https://sookocheff.com/post/modeling/littles-law/</link>
      <pubDate>Fri, 29 Nov 2019 14:03:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/modeling/littles-law/</guid>
      <description>&lt;p&gt;A queueing system can be described as the flow of items through a queue.
In a queueing system, items arrive at some rate to the system and join one
or more queues inside the system. These items receive some kind of
service, and when the work is done, they depart the system.&lt;/p&gt;
&lt;figure&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;assets/queueing-system.png&#34;/&gt; &lt;figcaption&gt;
            A simple queueing system
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Little’s Law is a pretty simple model of &lt;a href=&#34;https://en.wikipedia.org/wiki/Queueing_theory&#34;&gt;queueing
systems&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;$$
L=\lambda W
$$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Little’s Law says that the average number of items in a queueing system,
denoted \(L\), equals the average arrival rate of items in the system,
\(\lambda\), multiplied by the average waiting time of an item in the
system, \(W\).&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why I’m not (too) worried about Python 2</title>
      <link>https://sookocheff.com/post/python/why-im-not-too-worried-about-python-2/</link>
      <pubDate>Mon, 25 Nov 2019 09:53:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/python/why-im-not-too-worried-about-python-2/</guid>
      <description>&lt;p&gt;Python 2 will retire in about &lt;a href=&#34;https://pythonclock.org/&#34;&gt;one month&lt;/a&gt;. Given
many organizations continued reliance on it, you may be asking “Now What?”
What does this change mean for a company that heavily relies on
a deprecated language?&lt;/p&gt;
&lt;p&gt;Many times, the Python 2 deployed in an organization still generates a lot
of value. Yet as this code continues to age, you expose ourselves to
potential security vulnerabilities with fewer avenues to address them. To
continue running Python 2 and safely address this challenge, you have three
options:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Riding the Architecture Elevator</title>
      <link>https://sookocheff.com/post/architecture/riding-the-architecture-elevator/</link>
      <pubDate>Tue, 01 Oct 2019 19:40:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/riding-the-architecture-elevator/</guid>
      <description>&lt;p&gt;Large organizations have a lot of layers. From the C-Suite that is
concerned about strategy and vision, to middle management who are
executing on projects and programs, down to individual contributors
working on project features. These layers provide a number of advantages,
all derived from being able to better manage complexity. For example,
layers provide a nice separation of concerns: as a software engineer,
I don’t have to worry about tax codes and payroll because the finance
department can take care of this. As an intern, I don’t need to worry
about the global marketing strategy, I can just take care of implementing
the widgets we need delivered to customers.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Does WebRTC Work?</title>
      <link>https://sookocheff.com/post/networking/how-does-web-rtc-work/</link>
      <pubDate>Tue, 17 Sep 2019 06:47:51 +0000</pubDate>
      <guid>https://sookocheff.com/post/networking/how-does-web-rtc-work/</guid>
      <description>&lt;p&gt;To deliver real-time communication (RTC) from browser to browser requires
a lot of technologies that work well together: audio and video processing,
application and networking APIs, and additional network protocols that for
real-time streaming. The end result is WebRTC — over a dozen different
standards for the application protocols and browser APIs that enable
real-time communication for the web.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Does LTE Work?</title>
      <link>https://sookocheff.com/post/networking/how-does-lte-work/</link>
      <pubDate>Tue, 30 Jul 2019 09:01:52 +0000</pubDate>
      <guid>https://sookocheff.com/post/networking/how-does-lte-work/</guid>
      <description>&lt;p&gt;There is no one-size-fits-all cellular network used across the world, and
trying to understand how cellular technology works across all the
different uses cases is difficult, if not impossible, in a short blog
post. So, rather than trying to understand every possible standard, this
article will focus solely on LTE networks. Fortunately, competing
standards and implementations are roughly similar and we can extrapolate
any lessons learned about LTE to other cellular networks without much
difficulty.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Does WiFi Work?</title>
      <link>https://sookocheff.com/post/networking/how-does-wifi-work/</link>
      <pubDate>Wed, 10 Jul 2019 06:54:45 +0000</pubDate>
      <guid>https://sookocheff.com/post/networking/how-does-wifi-work/</guid>
      <description>&lt;p&gt;WiFi, technically specified in the IEEE 802.11 set of standards, is one of
the most widely deployed wireless standards in the world. Chance are the
device you are using to read this article has is WiFi enabled. WiFi is
a straightforward extension of &lt;a href=&#34;https://sookocheff.com/post/networking/how-does-ethernet-work/&#34;&gt;Ethernet&lt;/a&gt;, with some slight
adaptations for using radio instead of copper wire as the communication
channel.&lt;/p&gt;
&lt;p&gt;Like Ethernet, WiFi has no central process that controls which device is
allowed to transmit data at any point in time. Instead, each device
decides on its own, and all devices must work together to guarantee good
shared channel performance. With Ethernet, the protocol senses when the
communication channel is busy and waits until it is free before sending
data (carrier sensing). Ethernet also adds a collision detection protocol
as an optimization. If a collision is detected, nodes stop sending data
and use a randomized backoff algorithm to decide when to begin sending
again. Together, these algorithms form the carrier-sense multiple access
with collision &lt;em&gt;detection&lt;/em&gt; algorithm (CSMA/CD). WiFi uses a similar strategy
to Ethernet, but is restricted by the communication channel — there is no
reliable way to detect collisions using radio waves. Therefore, instead of
collision detection, WiFi uses a collision avoidance strategy defined by
the carrier-sense multiple access with collision &lt;em&gt;avoidance&lt;/em&gt; algorithm
(CSMA/CA).&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Does Ethernet Work?</title>
      <link>https://sookocheff.com/post/networking/how-does-ethernet-work/</link>
      <pubDate>Mon, 08 Jul 2019 05:59:12 +0000</pubDate>
      <guid>https://sookocheff.com/post/networking/how-does-ethernet-work/</guid>
      <description>&lt;p&gt;Ethernet is a technology developed a Xerox PARC in 1973 and 1974 to
support local area networking. It has since been expanded to include
a whole family of technologies that support various network architectures
and topologies as part of the IEEE 802.3 working group dedicated to
supporting networking using physical connections and devices (i.e. not
wireless).&lt;/p&gt;
&lt;p&gt;Ethernet was built with the assumption that all computers on
a network use a shared communication channel. The primary problem with
using a shared connection is creating a sense of orderly traffic when an entire
network of computers wants to constantly transmit data over the same
channel. The core of that solution is sensing other node’s activity and
waiting until the line is free and using collision detection to minimize
the amount of traffic on the network.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Wireless Networks and Shannon’s Law</title>
      <link>https://sookocheff.com/post/networking/wireless-networks-and-shannons-law/</link>
      <pubDate>Fri, 05 Jul 2019 06:32:12 +0000</pubDate>
      <guid>https://sookocheff.com/post/networking/wireless-networks-and-shannons-law/</guid>
      <description>&lt;p&gt;All wireless networks (Wi-Fi, Bluetooth, 3G, LTE, etc.) operate using
radio signals. Because they operate over the radio, all communication methods have
a maximum channel capacity, regardless of technology. This maximum
capacity was which is determined by the same underlying
principles of information theory developed by &lt;a href=&#34;https://en.wikipedia.org/wiki/Channel_capacity&#34;&gt;Claude Shannon during World
War II&lt;/a&gt;, known as
Shannon-Hartley theorem or Shannon&amp;rsquo;s Law. Shannon’s Law states that
This capacity relationship can be stated as:&lt;/p&gt;
&lt;p&gt;$$
{C=W\log _{2}\left( 1+{S \over N} \right)}
$$&lt;/p&gt;</description>
    </item>
    <item>
      <title>Curate Don’t Dictate</title>
      <link>https://sookocheff.com/post/architecture/curate-dont-dictate/</link>
      <pubDate>Mon, 24 Jun 2019 06:03:53 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/curate-dont-dictate/</guid>
      <description>&lt;p&gt;Inspiration for software architecture often comes from the world of
building architecture. In building architecture, the architect takes in
local building codes to understand construction requirements. They analyze
various building components like ductwork and furnaces, windows and doors,
and figure out where and when to use standard components and when to build
custom. They provide cost estimates for each of the components and for the
whole, and then build out a blueprint providing upfront design and
specification.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Tied to Machines Podcast — Architecture</title>
      <link>https://sookocheff.com/post/architecture/tied-to-machines-architecture/</link>
      <pubDate>Thu, 20 Jun 2019 10:04:38 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/tied-to-machines-architecture/</guid>
      <description>&lt;p&gt;I recently had the pleasure of being part of the &lt;a href=&#34;https://www.tiedtomachines.com/&#34;&gt;Tied to
Machines&lt;/a&gt; podcast. We talked about the
role of architecture, architectural leadership, and the intersection
between architecture and business.&lt;/p&gt;
&lt;p&gt;You can listen to the full episode
&lt;a href=&#34;https://www.tiedtomachines.com/podcast-player/114/kevin-sookocheff-architecture.mp3&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Principles of Architectural Leadership</title>
      <link>https://sookocheff.com/post/architecture/principles-of-architectural-leadership/</link>
      <pubDate>Thu, 06 Jun 2019 07:55:23 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/principles-of-architectural-leadership/</guid>
      <description>&lt;p&gt;Software is core to the operation of our business, and as architects, we
are the key conduit &lt;a href=&#34;https://sookocheff.com/post/architecture/architecture-as-business-analyst/&#34;&gt;between business and technology&lt;/a&gt;. Being
technical leaders within this intertwined relationship means that we have
a &lt;em&gt;responsiblity&lt;/em&gt; to make sure that our business decisions and our
technology decisions stay aligned. Being in this position demands
leadership skills that are equal or better than our technical skills, so
that we can effectively align business strategy with technical strategy,
communicate that strategy to teams, motivate both teams and individuals,
and influence outcomes.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Does UDP Work?</title>
      <link>https://sookocheff.com/post/networking/how-does-udp-work/</link>
      <pubDate>Wed, 29 May 2019 06:47:51 +0000</pubDate>
      <guid>https://sookocheff.com/post/networking/how-does-udp-work/</guid>
      <description>&lt;p&gt;The User Datagram Protocol (&lt;em&gt;UDP&lt;/em&gt;), first described in 1980 by &lt;a href=&#34;https://tools.ietf.org/html/rfc768&#34;&gt;RFC
768&lt;/a&gt;, offers a minimal set of functionality: there is no guarantee
of message delivery, no guarantee of message order, no congestion
avoidance, and no tracking of connection state. In fact, UDP is often
referred to as the &lt;em&gt;null protocol&lt;/em&gt;, because it offers little functionality
not already included in the IP layer.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Innovation with Constraints</title>
      <link>https://sookocheff.com/post/architecture/innovation-with-constraints/</link>
      <pubDate>Fri, 17 May 2019 14:07:51 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/innovation-with-constraints/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;One of the many paradoxes of human creativity is that it seems to benefit
from constraints. Although we [perceive] the imagination as requiring total
freedom, the reality of the creative process is that it&amp;rsquo;s often entangled
with strict conventions and formal requirements. Pop songs have choruses
and refrains; symphonies have four movements; plays have five acts;
painters still rely on the tropes of portraiture.&lt;/p&gt;
&lt;p&gt;&lt;cite&gt;&lt;a href=&#34;https://www.wired.com/2011/11/need-to-create-get-a-constraint/&#34;&gt;Jonah Lehrer&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Constraints can seem like the last thing you’d want for a creative
project, but they’re actually beneficial when it comes to doing good work.
Anyone who has written knows the hurdle of the blank page, and the feeling
that comes from being paralysed by innumerable choices. By restricting the
choices available to us, paralysis disappears and we can focus on the task
at hand. Don’t believe me? Consider the task of writing an entire story in
&lt;a href=&#34;https://en.wikipedia.org/wiki/For_sale%3A_baby_shoes%2C_never_worn&#34;&gt;less than six
words&lt;/a&gt;.
It seems impossible! How can you develop characters, expand a plot, and
tell a tale in six words? Here’s how Hemingway did it:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Does TCP Work?</title>
      <link>https://sookocheff.com/post/networking/how-does-tcp-work/</link>
      <pubDate>Wed, 15 May 2019 10:21:51 +0000</pubDate>
      <guid>https://sookocheff.com/post/networking/how-does-tcp-work/</guid>
      <description>&lt;p&gt;The transmission control protocol (TCP) does one job very well — it
creates an abstraction that makes an unreliable channel look like
a reliable network. For applications built over an unreliable network like
the Internet, TCP is a godsend that hides a lot of the inherent complexity
in building networked applications. A laundry list of TCP features that
application developers rely on every day includes: retransmission of lost
data, in-order data delivery, data integrity, and congestion control. This
article provides an introduction TCP, describing the structure of TCP
segments, how TCP connections are established, and the algorithms that
govern the flow of data between senders and receivers.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Do Websockets Work?</title>
      <link>https://sookocheff.com/post/networking/how-do-websockets-work/</link>
      <pubDate>Thu, 04 Apr 2019 13:40:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/networking/how-do-websockets-work/</guid>
      <description>&lt;p&gt;A WebSocket is a persistent connection between a client and server.
WebSockets provide a bidirectional, full-duplex communications channel
that operates over HTTP through a single TCP/IP socket connection. At its
core, the WebSocket protocol facilitates message passing between a client
and server. This article provides an introduction to the WebSocket
protocol, including what problem WebSockets solve, and an overview of how
WebSockets are described at the protocol level.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Zero Bug Policy</title>
      <link>https://sookocheff.com/post/process/zero-bug-policy/</link>
      <pubDate>Wed, 03 Apr 2019 06:44:16 +0000</pubDate>
      <guid>https://sookocheff.com/post/process/zero-bug-policy/</guid>
      <description>&lt;p&gt;A few years ago, a company I worked for was suffering from quality
problems. We were expanding into new areas, pushing the product in new
directions, and releasing new features quickly. As we pushed out new and
evolved products, quality declined. Everything came to a head when
customers began openly complaining about software quality. Our CTO stepped
in with a mandate to solve the quality problem. His approach? &lt;em&gt;The Zero
Bug Policy&lt;/em&gt; — no-one was allowed to work on new features until the number
of bugs in the product backlog was zero.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Does HTTP/2 Work?</title>
      <link>https://sookocheff.com/post/networking/how-does-http-2-work/</link>
      <pubDate>Mon, 01 Apr 2019 11:13:38 +0000</pubDate>
      <guid>https://sookocheff.com/post/networking/how-does-http-2-work/</guid>
      <description>&lt;p&gt;&lt;em&gt;Note: To make this easier to read (and write), &lt;strong&gt;h1&lt;/strong&gt; may be used in
place of HTTP/1, and &lt;strong&gt;h2&lt;/strong&gt; may used in place of HTTP/2.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;HTTP/1 has a long and storied history. Originally developed as a sixty
page specification documented in &lt;a href=&#34;https://tools.ietf.org/html/rfc1945&#34;&gt;RFC
1945&lt;/a&gt;, it was designed to handle
text-based pages that leverage hypermedia to connect documents to each
other. Typical web pages would kilobytes of data. For example, the &lt;a href=&#34;http://info.cern.ch/hypertext/WWW/TheProject.html&#34;&gt;first
web page&lt;/a&gt; was a simple
text file with web links to other text documents. Now, the web is made up
of media-rich sites containing images, scripts, stylesheets, fonts, and
more. The size of a typical web page is &lt;a href=&#34;https://httparchive.org/reports/state-of-the-web#bytesTotal&#34;&gt;measured in megabytes rather than
kilobytes&lt;/a&gt;,
and the number of requests required to assemble a full page &lt;a href=&#34;https://httparchive.org/reports/state-of-the-web#reqTotal&#34;&gt;can be over one
hundred&lt;/a&gt;. The
reality of how web pages are built today does not match the reality that
HTTP/1 was designed to support.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Vendor Management is a Core Competency</title>
      <link>https://sookocheff.com/post/opinion/vendor-management-is-a-core-competency/</link>
      <pubDate>Thu, 21 Mar 2019 09:40:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/opinion/vendor-management-is-a-core-competency/</guid>
      <description>&lt;p&gt;Building and running a successful company requires an immense amount of
work and talent. It also requires focus. Companies cannot try and solve
problems with new and innovative techniques &lt;em&gt;everywhere&lt;/em&gt; they operate. It
is important to understand the areas your company &lt;em&gt;should&lt;/em&gt; innovate in,
and outside of that scope, use existing standards and off-the-shelf
software as much as possible. There is only so much innovation that
a company (or the market) is willing to bear and walking that line is
a key factor in developing a successful product on time and budget.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Overambitious API gateways</title>
      <link>https://sookocheff.com/post/api/overambitious-api-gateways/</link>
      <pubDate>Fri, 22 Feb 2019 09:21:53 +0000</pubDate>
      <guid>https://sookocheff.com/post/api/overambitious-api-gateways/</guid>
      <description>&lt;p&gt;In a microservices architecture, an API gateway can help address a number
of challenges: providing a stable endpoint for clients to call, allowing
an easy process for releasing new endpoints, or handling SSL termination
on behalf of services, to name a few. So how do we decide what features of an API gateway to
adopt, and which to leave behind? This article highlights the key
functions that an API gateway can provide, suggests the scope of problem
that API gateways are well-suited to solve, and cautions against the
features that make API gateways too ambitious.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Putting the R in D</title>
      <link>https://sookocheff.com/post/architecture/putting-the-r-in-d/</link>
      <pubDate>Mon, 28 Jan 2019 19:40:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/putting-the-r-in-d/</guid>
      <description>&lt;p&gt;The Research and Development department would appear to give equal weight
to both research and development by virtue of naming, yet there are few
engineers who would claim that research is a primary responsibility of
their job. Between working on product features, planning sprints, fixing
bugs, and attending meetings there is little time left for research. But
what is the cost of foregoing research in favour of development? In this
article, I consider the economic cost of ignoring research and argue that
focusing solely on development is harmful to both product and engineering.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Fault-Tolerance and Data Consistency Using Distributed Sagas</title>
      <link>https://sookocheff.com/post/architecture/fault-tolerance-and-data-consistency-using-distributed-sagas/</link>
      <pubDate>Thu, 06 Dec 2018 14:55:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/fault-tolerance-and-data-consistency-using-distributed-sagas/</guid>
      <description>&lt;p&gt;While microservices have become the defacto architectural pattern for
building modern systems, they come with their own set of challenges. Key
among them is ensuring application data consistency when data is spread
over multiple databases. This article discusses one solution to this
problem, &lt;em&gt;distributed sagas&lt;/em&gt;. Distributed sagas provide consistency
guarantees for systems spanning multiple databases in the face of failure
using a clear and manageable implementation pattern. A saga is highly
related to a finite state machines that moves consistently through a set
of states, ensuring at each step that some conditions hold.&lt;/p&gt;</description>
    </item>
    <item>
      <title>IaaS, PaaS, SaaS and Infrastructure</title>
      <link>https://sookocheff.com/post/opinion/iaas-paas-saas-infrastructure/</link>
      <pubDate>Tue, 23 Oct 2018 15:03:32 +0000</pubDate>
      <guid>https://sookocheff.com/post/opinion/iaas-paas-saas-infrastructure/</guid>
      <description>&lt;p&gt;Infrastructure is undergoing a significant paradigm shift. At my first job
as a software developer, scaling our infrastructure meant buying
a physical machine and installing it in a rack, setting up the system
images and base software by hand, configuring the network using some shell
scripts, and finally, making it available for developers to install
software. Now, with the advent of cloud computing, the same capabilities
— installing and running software — are available on-demand.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Alpha Conversion</title>
      <link>https://sookocheff.com/post/fp/alpha-conversion/</link>
      <pubDate>Thu, 18 Oct 2018 09:16:45 -0600</pubDate>
      <guid>https://sookocheff.com/post/fp/alpha-conversion/</guid>
      <description>&lt;p&gt;&lt;em&gt;Alpha conversion&lt;/em&gt; (also written \(\alpha\)-conversion) is a way of
removing name clashes in expressions.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A name clash arises when a \(\beta\)-reduction places an expression
with a free variable in the scope of a bound variable with the same name
as the free variable.&lt;/p&gt;
&lt;p&gt;— &lt;cite&gt;Greg Michaelson, An Introduction to Functional Programming
Through Lambda Calculus&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When we are performing a \(beta\)-reduction it is possible that the
variable name in an inner expression is the same as a variable name in an
outer expression. For example, consider&lt;/p&gt;</description>
    </item>
    <item>
      <title>Beta Reduction</title>
      <link>https://sookocheff.com/post/fp/beta-reduction/</link>
      <pubDate>Thu, 04 Oct 2018 09:16:45 -0600</pubDate>
      <guid>https://sookocheff.com/post/fp/beta-reduction/</guid>
      <description>&lt;p&gt;Formally, &lt;em&gt;beta reduction&lt;/em&gt; (also written \(\beta\)-reduction) is the
replacement of a bound variable in a function body with a function
argument. The purpose of \(\beta\)-reduction is to compute the result
of a function by function application using specific rules.&lt;/p&gt;
&lt;p&gt;More formally, the beta reduction rule states that a function application
of the form \((\lambda x.t)s\) reduces to the term \(t[x := s]\). The
term \(t[x := s]\) means that all instances of \(x\) in \(t\) are
replaced with \(s\). The \(\rightarrow\) syntax is used as
a shorthand for beta reduction. We can specify beta-reduction explicitly
using the notation \((\lambda x.t)s \rightarrow t[x := s]\), which means
that the beta reduction of \((\lambda x.t)s)\) is \(t[x := s]\). The
beta reduction removes the \(\lambda\) symbol and resolves to the
function’s body with the argument \(s\) substituted into the body.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Building Stateful Services with Kubernetes</title>
      <link>https://sookocheff.com/post/kubernetes/building-stateful-services/</link>
      <pubDate>Tue, 02 Oct 2018 10:38:23 -0600</pubDate>
      <guid>https://sookocheff.com/post/kubernetes/building-stateful-services/</guid>
      <description>&lt;p&gt;The Kubernetes sweet-spot is running stateless microservices that can
scale horizontally. By keeping state out of your application, Kubernetes
can seamlessly add, remove, or restart pods to keep your service healthy
and scalable. Developing a stateless application is, without question, the
easiest way to ensure that your app can scale with Kubernetes. However,
there are some workloads that do not run effectively in a stateless way,
and for that, Kubernetes offers a few tools for developing stateful
applications: &lt;em&gt;leader election&lt;/em&gt;, &lt;em&gt;StatefulSets&lt;/em&gt; and &lt;em&gt;session affinity&lt;/em&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Eta Reduction</title>
      <link>https://sookocheff.com/post/fp/eta-conversion/</link>
      <pubDate>Thu, 27 Sep 2018 10:16:45 -0600</pubDate>
      <guid>https://sookocheff.com/post/fp/eta-conversion/</guid>
      <description>&lt;p&gt;The purpose of eta reduction (also written \(\eta\)-reduction) is to
drop an abstraction over a function to simplify it. This is possible when
there is nothing more that a function can do to its argument. For example,
imagine that we have a simple function \( f\ x = g\ x \). Both \(g\)
and \(f\) take the same argument, \(x\), and the function application
function results in the same value (specified by the equality symbol).
Since both \(f\) and \(g\) take the same argument and produce the same
result, we can simplify the equation to just \(f = g\). In lambda
calculus, this simplification is called \(\eta\)-reduction.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Testing in Production — Building Observable Distributed Systems</title>
      <link>https://sookocheff.com/post/architecture/testing-in-production/</link>
      <pubDate>Tue, 25 Sep 2018 09:40:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/testing-in-production/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Complex systems exhibit unexpected behavior.&lt;/p&gt;
&lt;p&gt;— &lt;cite&gt;John Gall, The Systems Bible&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One reaction to the myriad failure cases we encounter with distributed
systems is to add more testing. Unfortunately, testing is a &lt;em&gt;best-effort&lt;/em&gt;
verification of system correctness — we simply cannot predict the failure
cases that will happen in production. What’s more, any environment that we
use to verify system behaviour is — at best — a pale imitation of our
production environment. An alternative to adding more tests is to add more
monitoring and alerting so we know as soon as possible that a system shows
signs of degradation. Unfortunately, monitoring and alerting suffers from
the same faults as testing — we monitor for behaviour that is predictable
in nature or that we have experienced in the past. Together, monitoring
and testing try to enumerate all possible permutations of partial and
total system failure. Unfortunately, they only provide a &lt;em&gt;simulation&lt;/em&gt; of
how you expect a system to actually function in production.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Normal, Applicative and Lazy Evaluation</title>
      <link>https://sookocheff.com/post/fp/evaluating-lambda-expressions/</link>
      <pubDate>Tue, 18 Sep 2018 10:26:45 -0600</pubDate>
      <guid>https://sookocheff.com/post/fp/evaluating-lambda-expressions/</guid>
      <description>&lt;p&gt;A lambda expression is said to be in &lt;em&gt;normal form&lt;/em&gt; if it cannot be reduced
any further, meaning that the expression no longer contains any function
applications. More formally, a reducible expression is called a &lt;em&gt;redex&lt;/em&gt;,
and a lambda expression is in normal form when it contains no more
redexes.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Redex&lt;/dt&gt;
&lt;dd&gt;A reducible function expression.&lt;/dd&gt;
&lt;dt&gt;Normal Form&lt;/dt&gt;
&lt;dd&gt;A lambda expression that contains no redexes.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Given a lambda expression, there are two primary strategies for reducing it to
normal form: normal-order evaluation, or applicative-order evaluation.
This article discusses both methods, their pros and cons, and an
alternative evaluation strategy that combines the pros from both — lazy
evaluation.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Representing Pairs and Lists in Lambda Calculus</title>
      <link>https://sookocheff.com/post/fp/representing-pairs-and-lists-in-lambda-calculus/</link>
      <pubDate>Fri, 07 Sep 2018 09:20:45 -0600</pubDate>
      <guid>https://sookocheff.com/post/fp/representing-pairs-and-lists-in-lambda-calculus/</guid>
      <description>&lt;p&gt;Having covered &lt;a href=&#34;https://sookocheff.com/post/fp/typed-lambda-calculus/&#34;&gt;types&lt;/a&gt;, let’s now turn our attention to lists. Lists are general purpose
data structures for storing sequences of items. In lambda calculus, lists
are represented using pairs, with the first item of the pair representing
the head of the list, and the second item representing the rest of the
list. A special value, nil, at as the second item of the pair terminates
the list.&lt;/p&gt;
&lt;h2 id=&#34;pairs&#34;&gt;Pairs&lt;/h2&gt;
&lt;p&gt;Let’s start by focusing on pairs (or tuples). A pair is built from two
arguments, \(a\) and \(b\), and returns a function \(f\) enclosing those two
arguments:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Typed Lambda Calculus</title>
      <link>https://sookocheff.com/post/fp/typed-lambda-calculus/</link>
      <pubDate>Tue, 21 Aug 2018 09:26:45 -0600</pubDate>
      <guid>https://sookocheff.com/post/fp/typed-lambda-calculus/</guid>
      <description>&lt;p&gt;Lambda calculus is a very simple language. If you take away any syntactic
sugar, all you are left with is functions that take arguments and return
results. You can use these simple building blocks to construct functions
that represent &lt;a href=&#34;https://sookocheff.com/post/fp/introducing-lambda-calculus/&#34;&gt;numbers and arithmetic&lt;/a&gt;, but there is no way
to restrict, for example, arithmetic functions to require numeric
operands. This is where types come in. Generally speaking, types allow you
to control the use of functions so that only meaningful combinations of
inputs and outputs are used.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Guide to the Kubernetes Networking Model</title>
      <link>https://sookocheff.com/post/kubernetes/understanding-kubernetes-networking-model/</link>
      <pubDate>Wed, 11 Jul 2018 13:27:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/kubernetes/understanding-kubernetes-networking-model/</guid>
      <description>&lt;p&gt;Kubernetes was built to run distributed systems over a cluster of
machines. The very nature of distributed systems makes networking
a central and necessary component of Kubernetes deployment, and
understanding the Kubernetes networking model will allow you to correctly
run, monitor and troubleshoot your applications running on Kubernetes.&lt;/p&gt;
&lt;p&gt;Networking is a vast space with a lot of mature technologies. For people
unfamiliar with the landscape, this can be uncomfortable because most
people have existing preconceived notions about networking, and there are
a lot of both new and old concepts to understand and fit together into
a coherent whole. A non-exhaustive list might include technologies like
network namespaces, virtual interfaces, IP forwarding, and network address
translation. This guide intends to demystify Kubernetes networking by
discussing each of Kubernetes dependent technologies along with
descriptions on how those technologies are used to enable the Kubernetes
networking model.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Infrastructure in an Age of Commodities</title>
      <link>https://sookocheff.com/post/architecture/infrastructure-in-an-age-of-commodities/</link>
      <pubDate>Tue, 19 Jun 2018 15:53:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/infrastructure-in-an-age-of-commodities/</guid>
      <description>&lt;p&gt;Early computers were described using mathematical notation and theoretical
constructions, which were then translated by enterprising machinists into
custom built calculation engines. The first computer programmers using
these machines built applications directly in hardware by plugging
together wires and sockets in varying configurations. Even with these
short-comings, the value of general purpose computing machines was
evident. As companies began to realize the utility of computing, they saw
computing as a means for differentiating themselves from their
competitors.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Recursive Lambda Functions the Y-Combinator</title>
      <link>https://sookocheff.com/post/fp/recursive-lambda-functions/</link>
      <pubDate>Mon, 11 Jun 2018 11:38:45 -0600</pubDate>
      <guid>https://sookocheff.com/post/fp/recursive-lambda-functions/</guid>
      <description>&lt;p&gt;In a purely functional language — like lambda calculus — programs are
expressed as nested function calls. Repetition in such an environment
requires that nesting of function calls continues until some condition is
met. During the repetition, each function passes its result to the next
function in the nested chain and this repetition is completed when a test
for some condition passes. The repetitive behaviour I’ve just described is &lt;em&gt;recursion&lt;/em&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Simplifying Lambda Syntax</title>
      <link>https://sookocheff.com/post/fp/simplifying-lambda-syntax/</link>
      <pubDate>Fri, 25 May 2018 09:26:45 -0600</pubDate>
      <guid>https://sookocheff.com/post/fp/simplifying-lambda-syntax/</guid>
      <description>&lt;p&gt;Evaluating lambda functions requires using lots of brackets, which can
be tedious and are a major source of error for evaluating expressions by
hand. To simplify expressions, you can omit brackets when it is clear what
the intention of the function is. Particularly, a function application can
omit the brackets surrounding each individual parameter and assume
the function is applied to the nearest argument. So, instead of expressing
a function of three arguments as&lt;/p&gt;</description>
    </item>
    <item>
      <title>Introducing Lambda Calculus</title>
      <link>https://sookocheff.com/post/fp/introducing-lambda-calculus/</link>
      <pubDate>Fri, 27 Apr 2018 09:26:45 -0600</pubDate>
      <guid>https://sookocheff.com/post/fp/introducing-lambda-calculus/</guid>
      <description>&lt;p&gt;Lambda calculus provides some of the foundational structures that
functional programming is built from. It therefore seems fitting to start
my journey through functional programming with a thorough examination of
lambda calculus. This first post will introduce Lambda calculus with
references to the book &lt;a href=&#34;https://www.amazon.ca/Introduction-Functional-Programming-Through-Calculus/dp/0486478831&#34;&gt;An Introduction to Functional Programming Through
Lambda Calculus&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;syntax&#34;&gt;Syntax&lt;/h2&gt;
&lt;p&gt;The complete syntax for Lambda calculus is surprisingly small and
comprehensible. This section lists the syntax in its entirety, while
following sections break the syntax down to explain each part.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Principled Approach to Architecture</title>
      <link>https://sookocheff.com/post/architecture/a-principled-approach-to-architecture/</link>
      <pubDate>Fri, 23 Mar 2018 14:39:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/a-principled-approach-to-architecture/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;A principle is a concept or value that is a guide for behaviour or
evaluation.&lt;/p&gt;
&lt;p&gt;— &lt;a href=&#34;https://en.wikipedia.org/wiki/Principle&#34;&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This post presents a principled approach to architecture. These principles
specify what I believe is important about architecture, without diving
into any details about how an architect should work. No matter how an
architect works day-to-day, by following principles, you can be sure you
are providing value in the right areas.&lt;/p&gt;
&lt;p&gt;As usual, this post is personal opinion, and I’m interested in hearing any
differing or similar opinions in the comments.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Range, Domain, and Codomain</title>
      <link>https://sookocheff.com/post/fp/domain-range-codomain/</link>
      <pubDate>Fri, 09 Mar 2018 10:26:45 -0600</pubDate>
      <guid>https://sookocheff.com/post/fp/domain-range-codomain/</guid>
      <description>&lt;p&gt;Three common terms come up whenever we talk about functions: domain, range,
and codomain. This post clarifies what each of those terms mean.&lt;/p&gt;
&lt;p&gt;Before we start talking about domain and range, lets quickly recap what a function is:&lt;/p&gt;
&lt;figure&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;color-function.svg&#34;/&gt; 
&lt;/figure&gt;

&lt;blockquote&gt;
&lt;p&gt;A function relates each element of a set
with exactly one element of another set
(possibly the same set).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.mathsisfun.com/sets/function.html&#34;&gt;Math is Fun&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;That is, a function relates an input to an output. &lt;em&gt;But&lt;/em&gt;, not all input
values have to work, and not all output values. For example, you can
imagine a function that only works for positive numbers, or a function
that only returns natural numbers. To more clearly specify the types and
values of a functions input and output, we use the terms domain, range,
and codomain.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Functional Microservices</title>
      <link>https://sookocheff.com/post/architecture/functional-microservices/</link>
      <pubDate>Mon, 05 Mar 2018 09:08:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/functional-microservices/</guid>
      <description>&lt;p&gt;One proposed benefit of following a microservice architecture is that each
service can be developed, released, and supported independently. In theory
this allows development teams to work with less coordination and less
overhead, leading to faster development times. In practice, this is
difficult to achieve without some guidelines that make it work.&lt;/p&gt;
&lt;p&gt;The book &lt;a href=&#34;http://amzn.to/2td6nYA&#34;&gt;The Tao of Microservices&lt;/a&gt; provides two
such guidelines — transport independence, and pattern matching — that
create an environment allowing you to compose services. Service
composition is the holy grail of microservices, allowing you to build
progressively more complex functionality safely and efficiently. This post
discusses how transport independence and pattern matching allow you to
compose services, what service composition means in terms of functions,
and how you can use this composition to build complex services additively.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Functional Programming Learning Plan</title>
      <link>https://sookocheff.com/post/fp/a-functional-learning-plan/</link>
      <pubDate>Fri, 09 Feb 2018 10:26:45 -0600</pubDate>
      <guid>https://sookocheff.com/post/fp/a-functional-learning-plan/</guid>
      <description>&lt;p&gt;I’m documenting my journey from functional neophyte to (hopefully)
functional programmer by writing a series of blog posts on the topic. So
far I’ve
covered &lt;a href=&#34;https://sookocheff.com/post/fp/what-is-functional-programming/&#34;&gt;what functional programming &lt;em&gt;is&lt;/em&gt;&lt;/a&gt; and &lt;a href=&#34;https://sookocheff.com/post/fp/why-functional-programming/&#34;&gt;why you would
want to learn about it&lt;/a&gt;. In this post, I’m going to describe the resources I will be using to
become functionally fluent.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Although I have previously said I’m learning about functional programming,
I should be more specific. I do already have some middling experience with
Clojure and Lisp, but I have too many battle scars from running dynamic
languages in production to go down that path again. At this point in my
career, my experience dictates that any new code I write will be
statically typed. Because of this bias, I’m going to approach learning
functional programming through the lens of statically typed functional
languages. My learning plan will reflect that and help narrow the scope of
this project.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Practical Differences Between Functional and Imperative Programming</title>
      <link>https://sookocheff.com/post/fp/differences-between-imperative-and-functional/</link>
      <pubDate>Fri, 02 Feb 2018 10:26:45 -0600</pubDate>
      <guid>https://sookocheff.com/post/fp/differences-between-imperative-and-functional/</guid>
      <description>&lt;p&gt;I previously &lt;a href=&#34;https://sookocheff.com/post/fp/what-is-functional-programming/&#34;&gt;talked about what functional programming is&lt;/a&gt; by comparing it to
other programming paradigms. This post expands on that post to talk
specifically about practical differences between functional programming
and the paradigm most of us are intimately familiar with — imperative.
This post is punctuated with some quotes from the book &lt;a href=&#34;http://amzn.to/2FJgfPF&#34;&gt;An Introduction to
Functional Programming Through Lambda Calculus&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It’s worth noting that each of these practical differences are enabled
because of the power of &lt;a href=&#34;https://sookocheff.com/post/fp/why-functional-programming/&#34;&gt;referential transparency&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why Functional Programming? The Benefits of Referential Transparency</title>
      <link>https://sookocheff.com/post/fp/why-functional-programming/</link>
      <pubDate>Fri, 02 Feb 2018 10:26:45 -0600</pubDate>
      <guid>https://sookocheff.com/post/fp/why-functional-programming/</guid>
      <description>&lt;p&gt;Having covered &lt;a href=&#34;https://sookocheff.com/post/fp/what-is-functional-programming/&#34;&gt;what functional programming &lt;em&gt;is&lt;/em&gt;&lt;/a&gt;, I wanted to spend
a minute or two discussing why I want to learn functional programming in
the first place. I’m sure we have all heard vague things about
“side-effects”, “immutability”, and “composition”, but I wanted to dive
a bit deeper on the topic to describe what — to me — is important about
functional programming.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;referential-transparency&#34;&gt;Referential Transparency&lt;/h2&gt;
&lt;p&gt;The key differentiating feature of (pure) functional programs is that
they provide &lt;em&gt;referential transparency&lt;/em&gt;. An expression is said to be
referentially transparent if it can be replaced with its corresponding
value without changing the program&amp;rsquo;s behaviour.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Overcoming Optimism with a Premortem</title>
      <link>https://sookocheff.com/post/business/the-premortem/</link>
      <pubDate>Wed, 24 Jan 2018 10:03:45 -0600</pubDate>
      <guid>https://sookocheff.com/post/business/the-premortem/</guid>
      <description>&lt;p&gt;I’ve been reading the excellent book &lt;em&gt;&lt;a href=&#34;http://amzn.to/2Gc4QEL&#34;&gt;Thinking, Fast and Slow&lt;/a&gt;&lt;/em&gt;
by Daniel Kahneman and came across a strategy for dealing with a common
human behaviour problem that has direct impact on software development:
overconfidence.&lt;/p&gt;
&lt;p&gt;According to Kahneman’s research,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“overconfidence is a direct consequence of [how we think] that can be
tamed — but not vanquished.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In other words, our brains are wired to make overconfident predictions and
forecasts. In software development, this overconfidence usually presents
itself in estimates of the importance of projects to the business, the
success rate of new projects, and in development timelines. We all seem to
have an intuition that these biases exist, but what can we do to
counteract them? One idea presented by Kahneman’s colleague Gary Klein is
the &lt;em&gt;premortem&lt;/em&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>What is Functional Programming?</title>
      <link>https://sookocheff.com/post/fp/what-is-functional-programming/</link>
      <pubDate>Tue, 23 Jan 2018 10:26:45 -0600</pubDate>
      <guid>https://sookocheff.com/post/fp/what-is-functional-programming/</guid>
      <description>&lt;p&gt;I’m documenting my journey from functional neophyte to (hopefully)
functional programmer by writing a series of blog posts on the topic. This
is the first post describing what, exactly, the word &lt;em&gt;functional
programming&lt;/em&gt; means.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Functional programming is a programming paradigm that lives alongside
other programming paradigms. None of these paradigms have a precise,
unanimous definition or standard, and there is not real agreement on which
paradigm is better or worse for building particular types of software.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cloze Deletions</title>
      <link>https://sookocheff.com/post/language/cloze-deletions/</link>
      <pubDate>Mon, 08 Jan 2018 05:41:48 +0000</pubDate>
      <guid>https://sookocheff.com/post/language/cloze-deletions/</guid>
      <description>&lt;p&gt;This page provides a collection of premade Anki decks filled with cloze
deletion tests for learning a second language. Use the table below to find
the dataset for the language you speak (the native language), and the
language you wish to learn (the target language).&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Native Language&lt;/th&gt;
          &lt;th&gt;Target Language&lt;/th&gt;
          &lt;th&gt;Anki Package&lt;/th&gt;
          &lt;th&gt;Audio&lt;/th&gt;
          &lt;th&gt;CSV&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;English&lt;/td&gt;
          &lt;td&gt;French&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;eng_fra_clozes.apkg&#34;&gt;eng_fra.apkg&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;eng_fra_audio.zip&#34;&gt;eng_fra.zip&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;eng_fra_clozes.csv&#34;&gt;eng_fra.csv&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;English&lt;/td&gt;
          &lt;td&gt;German&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;eng_deu_clozes.apkg&#34;&gt;eng_deu.apkg&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;eng_deu_audio.zip&#34;&gt;eng_deu.zip&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;eng_deu_clozes.csv&#34;&gt;eng_deu.csv&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;English&lt;/td&gt;
          &lt;td&gt;Spanish&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;eng_spa_clozes.apkg&#34;&gt;eng_spa.apkg&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;eng_spa_audio.zip&#34;&gt;eng_spa.zip&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;eng_spa_clozes.csv&#34;&gt;eng_spa.csv&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;English&lt;/td&gt;
          &lt;td&gt;Italian&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;eng_ita_clozes.apkg&#34;&gt;eng_ita.apkg&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;eng_ita_audio.zip&#34;&gt;eng_ita.zip&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;eng_ita_clozes.csv&#34;&gt;eng_ita.csv&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;frequently-asked-questions&#34;&gt;Frequently Asked Questions&lt;/h2&gt;
&lt;h3 id=&#34;how-to-import-these-decks-into-anki&#34;&gt;How to Import these Decks into Anki&lt;/h3&gt;
&lt;p&gt;You can import the cloze deletions into Anki using the CSV file provided
for each language. To import a file, click the &lt;code&gt;File&lt;/code&gt; menu and then select
&lt;code&gt;Import&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Improving Test Coverage Using Exploratory Outcomes</title>
      <link>https://sookocheff.com/post/testing/improving-test-coverage-with-exploratory-outcomes/</link>
      <pubDate>Fri, 22 Dec 2017 08:12:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/testing/improving-test-coverage-with-exploratory-outcomes/</guid>
      <description>&lt;p&gt;In general, developers test features by focusing on the positive outcomes
— the so-called “happy paths”. Unfortunately, this optimism can blind us
to the less obvious or less probable outcomes that can cripple an
application. I found one way to counteract this tendency is to try and “go
beyond the happy path” by exploring the outcome of unhappy paths through
a feature. I came across this idea in the excellent book &lt;a href=&#34;http://amzn.to/2kVVtPI&#34;&gt;&lt;em&gt;Fifty Quick
Ideas to Improve Your Tests&lt;/em&gt;&lt;/a&gt; by Gojko Adzic,
David Evans, and Tom Roden, and expanded upon the book &lt;a href=&#34;http://amzn.to/2CXGdZR&#34;&gt;Writing Great
Specifications&lt;/a&gt; by Kamil Nicieja.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Bulk Generating Cloze Deletions for Learning a Language with Anki</title>
      <link>https://sookocheff.com/post/language/bulk-generating-cloze-deletions-for-learning-a-language-with-anki/</link>
      <pubDate>Wed, 20 Dec 2017 11:14:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/language/bulk-generating-cloze-deletions-for-learning-a-language-with-anki/</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;em&gt;tldr; Looking to learn a language using cloze deletions and Anki?
&lt;a href=&#34;https://sookocheff.com/post/language/cloze-deletions/&#34;&gt;Click here.&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One challenge in learning a second language is the sheer amount of
vocabulary required for fluency. For example, &lt;a href=&#34;https://www.economist.com/blogs/johnson/2013/05/vocabulary-size&#34;&gt;one
study&lt;/a&gt;
has shown that the average eight year old knows 8000 words, while the
average adult might know somewhere between 20,000 and 35,000 words.
University graduates might know upwards of 50,000 words depending on their
specialization.&lt;/p&gt;
&lt;p&gt;As an adult learning a second language, exposure to a lot of different
words in their context is one of the best ways to learn vocabulary.
A common test for learning words in context is called a &lt;em&gt;cloze test&lt;/em&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Building Empathic Software Using Specification by Example</title>
      <link>https://sookocheff.com/post/architecture/building-empathic-software-using-specification-by-example/</link>
      <pubDate>Fri, 15 Dec 2017 14:55:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/building-empathic-software-using-specification-by-example/</guid>
      <description>&lt;p&gt;In most organizations, software development is split between two groups
— product management and engineering. Product management is focused on
&lt;em&gt;building the right system&lt;/em&gt;. This requires product managers to meet with
users, try and understand their needs, and develop solutions that meet
those needs. To actually develop the solution, product managers must
involve engineers who are focused on &lt;em&gt;building the system right&lt;/em&gt; — writing
the code, making it stable, and supporting it in production.
Unfortunately, there exists an uncomfortable gap between product managers
and engineers that forces the product manager to explain features in terms
that an engineer can implement, and that forces the engineers to explain
technological constraints to product managers in terms that a product
manager can understand. To bridge this gap requires careful and
considerate communication. It requires &lt;em&gt;empathy&lt;/em&gt; from both product
managers and engineers.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Fast Does it Need to be Anyways? The QUPER Model of Analyzing Non-Functional Requirements</title>
      <link>https://sookocheff.com/post/architecture/how-fast-does-it-need-to-be-anyways/</link>
      <pubDate>Thu, 23 Nov 2017 13:32:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/how-fast-does-it-need-to-be-anyways/</guid>
      <description>&lt;p&gt;We all know that a page that loads in three seconds will provide a negative user
experience. But does having every page load in less than one second make
a meaningful difference? How can you tell? When is enough &amp;hellip; enough?
Non-functional requirements such as performance are often not precise
enough to be specified as discrete numbers. Rather, they work on a sliding
scale of acceptability.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Would slightly better performance be significantly more valuable
from a market perspective? Would significantly better
performance be just slightly more expensive to implement?
When dealing with performance, usability, reliability and
so forth, we often end up in a difficult trade-off analysis.&lt;/p&gt;</description>
    </item>
    <item>
      <title>What is CQRS?</title>
      <link>https://sookocheff.com/post/architecture/what-is-cqrs/</link>
      <pubDate>Tue, 08 Aug 2017 19:40:16 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/what-is-cqrs/</guid>
      <description>&lt;p&gt;Bertrand Meyer first introduces the principle of &lt;a href=&#34;https://martinfowler.com/bliki/CommandQuerySeparation.html&#34;&gt;Command Query
Separation&lt;/a&gt; in
his book &lt;a href=&#34;http://amzn.to/2BhauSX&#34;&gt;Object-Oriented Software
Construction&lt;/a&gt;. The
principle states that a well designed object should have methods that are
either &lt;em&gt;commands&lt;/em&gt; or &lt;em&gt;queries&lt;/em&gt;. A &lt;em&gt;command&lt;/em&gt; changes the state of an
object, but does not return any data, while a &lt;em&gt;query&lt;/em&gt; returns data and
does not change any state. By dividing methods into these two categories,
you will have a better understanding of what does, and what does not,
change the state of your system.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Dissecting SQS FIFO Queues — Does Ordered and Exactly Once Messaging Really Exist?</title>
      <link>https://sookocheff.com/post/messaging/dissecting-sqs-fifo-queues/</link>
      <pubDate>Tue, 01 Aug 2017 09:41:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/messaging/dissecting-sqs-fifo-queues/</guid>
      <description>&lt;p&gt;At first glance, Amazon’s First-In-First-Out (FIFO) message queues provide
an excellent feature set for business-critical scenarios. With FIFO, the
order in which messages are sent and received is strictly preserved. With
exactly-once processing, message duplicates are not introduced into the
queue, and consumers control when a message is made available for
redelivery. Reading past the marketing hype, how well do FIFO queues work
in the real world?&lt;/p&gt;
&lt;p&gt;This article takes a deep dive into SQS FIFO queues to test the claims of
message ordering and exactly-once processing, paying particular care to
the conditions under which these claims hold. I show how exactly-once
processing can be achieved, and how that message ordering is preserved
through failure conditions. I conclude with an examination of the
relationship between in-order and exactly-once processing and atomic
broadcast and consensus.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Learning a Language with Amazon Polly and a Serverless Chalice App</title>
      <link>https://sookocheff.com/post/aws/learning-a-language-with-amazon-polly/</link>
      <pubDate>Fri, 28 Jul 2017 11:59:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/aws/learning-a-language-with-amazon-polly/</guid>
      <description>&lt;p&gt;For the past year I’ve been making a concerted effort to learn French
using the methods from the book &lt;a href=&#34;https://fluent-forever.com/&#34;&gt;Fluent
Forever&lt;/a&gt;, which is an excellent resource for
learning how to learn a language. For those not familiar with the
method, it boils down to this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Learn Pronunciation: knowing how to correctly pronounce words in your
target language makes everything else easier.&lt;/li&gt;
&lt;li&gt;Learn Frequently Used Words: not all words are created equal, learn the
most frequently used words first.&lt;/li&gt;
&lt;li&gt;Learn Grammar: put together grammatical sentences using the words you
already know.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you turn your head to the side and squint at that list, it somewhat
resembles the steps you would take to learn a language as an infant
— first understand the sounds of the language, then learn words (“mommy”,
“daddy”), and finally put together correct sentences. In addition, as an
infant you have a constant source of high quality input helping you learn
words and grammar. You can imagine the following “conversation” between an
adult and a hungry child:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Evolving Messaging For Microservices: A Retrospective from Building Workiva’s Messaging Platform</title>
      <link>https://sookocheff.com/post/messaging/evolving-messaging-for-microservices/</link>
      <pubDate>Wed, 28 Jun 2017 18:29:21 +0000</pubDate>
      <guid>https://sookocheff.com/post/messaging/evolving-messaging-for-microservices/</guid>
      <description>&lt;p&gt;Workiva’s original product — supporting the mundane task of &lt;a href=&#34;https://www.workiva.com/solutions/sec-reporting&#34;&gt;filing
documents with the SEC&lt;/a&gt;
— was so innovative that within its first 5 years it was being used by
more than 65 percent of the Fortune 500 and generating more than $100
million in annual revenue. During that explosion in growth, the software
development team focused solely on supporting and expanding the existing
software stack. However, after several years of growth and expansion
maintaining and extending that single code base became unsustainable.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to create a functional VPC using CloudFormation</title>
      <link>https://sookocheff.com/post/aws/how-to-create-a-vpc-using-cloudformation/</link>
      <pubDate>Wed, 07 Jun 2017 20:59:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/aws/how-to-create-a-vpc-using-cloudformation/</guid>
      <description>&lt;p&gt;This tutorial walks through how to create a fully functional Virtual
Private Cloud in AWS using CloudFormation. At the end of the tutorial, you
will have a reproducible way to create a virtual cloud with three subnets,
a security group, and an internet gateway with SSH access for your IP
address. I’ve found this template useful for creating an isolated
environment to develop and test software.&lt;/p&gt;
&lt;p&gt;Full code for this tutorial is available on
&lt;a href=&#34;https://github.com/soofaloofa/cloudformation-templates&#34;&gt;Github&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Compiling private Java code from Leiningen</title>
      <link>https://sookocheff.com/post/clojure/compiling-java-code-with-leiningen/</link>
      <pubDate>Wed, 31 May 2017 11:15:08 +0000</pubDate>
      <guid>https://sookocheff.com/post/clojure/compiling-java-code-with-leiningen/</guid>
      <description>&lt;p&gt;For a recent project, I wanted to verify the correctness of a distributed
queue implementation based on &lt;a href=&#34;https://sookocheff.com/post/messaging/publish-subscribe-messaging-using-sqs/&#34;&gt;Amazon SQS&lt;/a&gt;. For
this, I turned to the &lt;a href=&#34;https://github.com/jepsen-io/jepsen&#34;&gt;Jepsen&lt;/a&gt;
library for verifying distributed systems. Jepsen is written in Clojure
and the first task was to get Jepsen to compile with a Java library hosted
on our internal Maven repository. I googled for a while, asked around, and
assembled instructions from a few different places. Here then, is a single
blog post summarizing the solution for future use.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Uploading Large Payloads through API Gateway</title>
      <link>https://sookocheff.com/post/api/uploading-large-payloads-through-api-gateway/</link>
      <pubDate>Wed, 10 May 2017 16:12:14 +0000</pubDate>
      <guid>https://sookocheff.com/post/api/uploading-large-payloads-through-api-gateway/</guid>
      <description>&lt;p&gt;API Gateway supports a reasonable payload size limit of 10MB. One way to
work within this limit, but still offer a means of importing large
datasets to your backend, is to allow uploads through S3. This article
shows how to use AWS Lambda to expose an S3 signed URL in response to an
API Gateway request. Effectively, this allows you to expose a mechanism
allowing users to securely upload data directly to S3, triggered by the
API Gateway.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Getting Started With TLA&#43;</title>
      <link>https://sookocheff.com/post/tlaplus/getting-started-with-tlaplus/</link>
      <pubDate>Thu, 20 Apr 2017 11:00:23 -0600</pubDate>
      <guid>https://sookocheff.com/post/tlaplus/getting-started-with-tlaplus/</guid>
      <description>&lt;p&gt;This post shows how to write your first simple TLA+ specification.&lt;/p&gt;
&lt;h2 id=&#34;what-is-a-specification&#34;&gt;What is a specification?&lt;/h2&gt;
&lt;p&gt;In software, the behaviour of a system is described as a sequence of
states. Mathematically, each state is expressed as a function &lt;em&gt;F(t)&lt;/em&gt;,
which represents the state of a system at time &lt;em&gt;t&lt;/em&gt;. To completely specify
a system, we write out each state to fully define the systems behaviour.&lt;/p&gt;
&lt;h2 id=&#34;a-simple-clock&#34;&gt;A simple clock&lt;/h2&gt;
&lt;p&gt;This example comes from Chapter 2 of the book &lt;a href=&#34;https://github.com/tlaplus/tlaplus&#34;&gt;Specifying
Systems&lt;/a&gt; by the creator of TLA+,
Leslie Lamport. If you are unfamiliar with the math used here, refer to
&lt;a href=&#34;https://sookocheff.com/post/tlaplus/basic-math-for-tlaplus/&#34;&gt;basic math&lt;/a&gt; for writing TLA+ article.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Basic Math for TLA&#43;</title>
      <link>https://sookocheff.com/post/tlaplus/basic-math-for-tlaplus/</link>
      <pubDate>Wed, 19 Apr 2017 11:00:23 -0600</pubDate>
      <guid>https://sookocheff.com/post/tlaplus/basic-math-for-tlaplus/</guid>
      <description>&lt;p&gt;At its most basic, TLA+ is a written description of what a system is
supposed to do. More specifically, TLA+ is a specification language for
formally defining the behavioural properties of a system.&lt;/p&gt;
&lt;p&gt;TLA+ is based on &lt;em&gt;temporal logic&lt;/em&gt;, which is built on top of first-order
logic and set theory, and provides some conveniences for working with
large specifications for complex systems. You can think of a TLA+
specification as mostly ordinary math and logic, glued together with
temporal logic for parts requiring it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>First Musings on TLA&#43;</title>
      <link>https://sookocheff.com/post/tlaplus/first-musings-on-tlaplus/</link>
      <pubDate>Tue, 18 Apr 2017 11:00:23 -0600</pubDate>
      <guid>https://sookocheff.com/post/tlaplus/first-musings-on-tlaplus/</guid>
      <description>&lt;p&gt;I’ve been helping define some concurrent algorithms and I’m struggling
with a number of issues: concurrent algorithms are difficult to design,
they are often difficult to implement, and, even after they are designed,
are difficult to guarantee that they are correct. This lead me into some
research on formal specifications for algorithms, and how they can help.
Finally, I settled on TLA+ as a viable tool for just such a problem.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: WebTables: Exploring the Power of Tables on the Web</title>
      <link>https://sookocheff.com/post/databases/webtables/</link>
      <pubDate>Wed, 29 Mar 2017 09:34:37 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/webtables/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=11659194181134800008&#34;&gt;WebTables: Exploring the Power of Tables on the Web&lt;/a&gt;. M.J. Cafarella et
al.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;WebTables is a project to extract and process HTML tables from Google’s
serach index. It attempts to answer two questions: what are some effective
techniques for searching structured data at search engine scale, and what
can be derived from analyzing a large corpus of HTML tables?&lt;/p&gt;
&lt;p&gt;Web documents often contain structured and relational data embedded in
HTML tables. The WebTables project extracted 14.1 billion English language
HTML tables and further filtered those down to 154 million tables that
contain structured data. From this data, we have the potential to
determine semantic information embedded in the web, create visualizations,
and integrate web documents into new applications.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: Combining Systems and Databases: A Search Engine Retrospective</title>
      <link>https://sookocheff.com/post/databases/combining-systems-and-databases/</link>
      <pubDate>Mon, 27 Mar 2017 06:00:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/combining-systems-and-databases/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=15869287167041695406&#34;&gt;Combining Systems and Databases: A Search Engine Retrospective&lt;/a&gt;.
Eric A. Brewer.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Search engines manage data and respond to queries, which provides some
similarities to databases. However, search engines are really an
application-specific system built to handle large datasets. This system
can leverage databases, or not, depending on the system goals. This paper
describes a search engine design that leverages the ideas and vocabulary
of the database community.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Publish-Subscribe Messaging Using Amazon SQS</title>
      <link>https://sookocheff.com/post/messaging/publish-subscribe-messaging-using-sqs/</link>
      <pubDate>Fri, 24 Mar 2017 18:29:21 +0000</pubDate>
      <guid>https://sookocheff.com/post/messaging/publish-subscribe-messaging-using-sqs/</guid>
      <description>&lt;p&gt;Amazon’s Simple Queue Service (SQS) provides durable messaging guarantees
and is an excellent backbone for messaging services. However, SQS does not
support “fan-out” of messages so that multiple consuming services can each
receive a copy of a message. This means that true publish-subscribe
messaging requires some additional work. This post describes some
architectural choices that provide durable publish-subscribe messaging
using SQS by tracking messaging subscribers using a database, and matching
published messages to interested subscribers.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: The Anatomy of a Large-Scale Hypertextual Web Search Engine</title>
      <link>https://sookocheff.com/post/databases/google/</link>
      <pubDate>Thu, 23 Mar 2017 06:07:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/google/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=9820961755208603037&#34;&gt;The Anatomy of a Large-Scale Hypertextual Web Search Engine&lt;/a&gt;.
Sergey Brin and Lawrence Page.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;This paper describes the underpinnings of the Google search engine. The
paper presents the initial Google prototype and describes the challenges
in scaling search engine technology to handle large datasets. At the time
of writing, the main goal of Google is to improve the quality of web
searches by taking advantage of the existing link data embedded in web
pages to calculate the quality of a page.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: Consistency Analysis in Bloom: a CALM and Collected Approach</title>
      <link>https://sookocheff.com/post/databases/calm/</link>
      <pubDate>Wed, 22 Mar 2017 06:07:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/calm/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=9165311711752272482&#34;&gt;Consistency Analysis in Bloom: a CALM and Collected
Approach&lt;/a&gt;.
Alvaro et al.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Distributed programming is difficult for even experienced developers to
get correct.  Understanding the tradeoff between consistency,
availability, and latency, while guaranteeing data correctness, provides
a wealth of problems for the application developer. This paper presents
a language and method for programmatically verifying distributed consistency.&lt;/p&gt;
&lt;h3 id=&#34;calm---consistency-and-logical-monotonicity&#34;&gt;CALM - Consistency and Logical Monotonicity&lt;/h3&gt;
&lt;p&gt;There is a connection between distributed consistency algorithms and
logical monotonicity, that is, our programs must be correct even in the
face of the delay and re-ordering of messages and data across different
nodes in a system. By designing programs with &lt;em&gt;order independence&lt;/em&gt;, we can
ensure that the logic of the system is maintained within a distributed
environment.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SQS or Kinesis? Comparing Apples to Oranges</title>
      <link>https://sookocheff.com/post/aws/comparing-kinesis-and-sqs/</link>
      <pubDate>Tue, 21 Mar 2017 11:59:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/aws/comparing-kinesis-and-sqs/</guid>
      <description>&lt;p&gt;When designing Workiva’s durable messaging system we took a hard look at
using Amazon’s Kinesis as the message storage and delivery mechanism. At
first glance, Kinesis has a feature set that looks like it can solve any
problem: it can store terabytes of data, it can replay old messages, and
it can support multiple message consumers. But if you dig a little deeper
you will find that Kinesis is well suited for a very particular use case,
and if your application doesn’t fit this use case, Kinesis may be a lot
more trouble than it’s worth.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Software Architecture as Business Analysis</title>
      <link>https://sookocheff.com/post/architecture/architecture-as-business-analyst/</link>
      <pubDate>Mon, 20 Mar 2017 09:39:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/architecture-as-business-analyst/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Architecture is the bridge between (often abstract) business goals and
the final (concrete) resulting system.&lt;/p&gt;
&lt;p&gt;– &lt;cite&gt;&lt;a href=&#34;http://amzn.to/2BfT89j&#34;&gt;&lt;em&gt;Software Architecture in Practice&lt;/em&gt;&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A software architect should act as a bridge between business stakeholders
and technical stakeholders. To be this bridge requires understanding the
business problem being solved, and being able to distill that problem into
a technical solution that a software team can implement. In essence, the
architect acts as a technical business analyst that helps to define the
needs of an organization and recommend solutions that deliver value to
stakeholders. It just so happens that an architect’s stakeholders include
project managers, software developers, management, and other software
architects. This article describes how a software architect can apply
methods from business analysis to make their job easier and to satisfy
these different stakeholders.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: The CQL continuous query language: semantic foundations and query execution</title>
      <link>https://sookocheff.com/post/databases/cql/</link>
      <pubDate>Fri, 17 Mar 2017 09:32:21 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/cql/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=17215743948117955326&#34;&gt;The CQL continuous query language: semantic foundations and query execution&lt;/a&gt;. Arasu et al.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;CQL is a derivation of the SQL query language developed for running
continuous queries over streams of data. The goals of the system are to
provide a precise set of language semantics for running such continuous
stream workloads. The paper starts by defining precise abstract semantics
for continuous queries that cover two data types — streams and relations
— and three classes of operators: ones that produce a relation from
a stream, one that produces a relation from other relations, and one that
produces a stream from a relation. These semantics are defined independent
of the underlying implementation. The second portion of this paper defines
how CQL instantiates these abstract semantics using existing SQL
specifications and some new CQL additions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: BlinkDB: Queries with Bounded Errors and Bounded Response Times on Very Large Data</title>
      <link>https://sookocheff.com/post/databases/blinkdb/</link>
      <pubDate>Sat, 04 Mar 2017 15:35:18 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/blinkdb/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=4916926405792203059&#34;&gt;BlinkDB: Queries with Bounded Errors and Bounded Response Times on Very Large Data&lt;/a&gt;.
Agarwal et al.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;BlinkDB is a massively parallel database that provides approximate results
for queries over large data sets. BlinkDB’s distinguishing feature is
providing the opportunity for users to trade response time for query
accuracy — partial results are returned with annotated error bars
describing their accuracy at the current point in time.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: Informix under CONTROL: Online Query Processing</title>
      <link>https://sookocheff.com/post/databases/informix-under-control/</link>
      <pubDate>Fri, 03 Mar 2017 11:59:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/informix-under-control/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=1434575511619007556&#34;&gt;Informix under CONTROL: Online Query
Processing&lt;/a&gt;.
J. M. Hellerstein et al.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;The CONTROL project attempts to improve the interaction between users and
computers during data analysis.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Traditional data analysis systems are a black box where a user enters
a query, and waits for some amount of time before receiving a result. The
CONTROL project aims to make this process interactive by continuously
providing approximate results that are improved over time. Implementing
such a system requires rethinking some fundamental tenants of database
systems. First, with interactive systems queries may never complete, but
instead they may be halted when results are “good enough”. Second,
interactive systems must be able to provide approximate results quickly
while maximizing the rate at which an accurate answer is found. This paper
explores the changes in database technology needed to support interactive
use cases.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Much is That Going to Cost Anyway? Calculating Cost of Goods Sold</title>
      <link>https://sookocheff.com/post/architecture/how-much-is-that-going-to-cost/</link>
      <pubDate>Sun, 26 Feb 2017 15:53:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/how-much-is-that-going-to-cost/</guid>
      <description>&lt;p&gt;One of the realities of running a business is that you will — at some
point — need to make money. This means you must sell something for more
than it cost to make it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Profit = Total Revenue - Total Expenses&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, to sell a service or feature (like a third-party API portal) at
a profit, we need to understand how much it costs to make it, so we know
how much to sell it for. In business parlance, the quantity we are looking
for is the &lt;em&gt;cost of goods sold&lt;/em&gt; — the accumulated costs used to create
a good, including direct labor, materials, and any overhead.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: An Array-Based Algorithm for Simultaneous Multidimensional Aggregates</title>
      <link>https://sookocheff.com/post/databases/an-array-based-algorithm-for-simultaneous-multidimensional-aggregates/</link>
      <pubDate>Mon, 20 Feb 2017 05:33:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/an-array-based-algorithm-for-simultaneous-multidimensional-aggregates/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=1761772586638103323&#34;&gt;An Array-Based Algorithm for Simultaneous Multidimensional
Aggregates&lt;/a&gt;.
Y. Zhao et al.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;One of the core functions of an OLAP system is computing aggregations and
group-by operations. This functionality has been characterized by the
“Cube” operator, which computes group-by aggregations over all possible
subsets of a specified dimension. As an example of the Cube operator,
consider a model with the dimensions &lt;em&gt;product&lt;/em&gt;, &lt;em&gt;store&lt;/em&gt;, &lt;em&gt;date&lt;/em&gt;, and the
measured value &lt;em&gt;sales&lt;/em&gt;. To compute the Cube for this data set requires
computing sales for all subsets of the dimensions: sales by product,
store, and date; sales by product and store; sales by product; etc. As
a user, I want the system to prepare these results for me in response to
ad-hoc queries or as part of a ETL job that prepares the data for
analysis. Because there is a lot of data involved, the challenge of
implementing the Cube operator is in computing these aggregations as
efficiently as possible.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Italics in Vim</title>
      <link>https://sookocheff.com/post/vim/italics/</link>
      <pubDate>Thu, 16 Feb 2017 19:16:09 -0600</pubDate>
      <guid>https://sookocheff.com/post/vim/italics/</guid>
      <description>&lt;p&gt;I write Markdown using Vim and the
&lt;a href=&#34;https://github.com/reedes/vim-pencil&#34;&gt;vim-pencil&lt;/a&gt; plugin and one of the
things that particularly bothered me was that, by default, iTerm2 and the
&lt;a href=&#34;http://ethanschoonover.com/solarized&#34;&gt;solarized&lt;/a&gt; colour scheme did not
support &lt;em&gt;italic text&lt;/em&gt;. I finally sat down this evening and got this
working. Really, I just found and watched Greg Hurrel’s &lt;a href=&#34;https://www.youtube.com/watch?v=n1cKtZfwOgQ&amp;amp;feature=youtu.be&amp;amp;list=PLwJS-G75vM7kFO-yUkyNphxSIdbi_1NKX&amp;amp;t=17&#34;&gt;YouTube video
explaining the whole
thing&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;To enable italics requires updating the terminfo database. Terminfo
enables programs to use the terminal in a device-independent manner. For
us, this means that it allows applications to lookup the correct escape
codes for displaying italics. If the terminfo database has the correct
escape codes present in the database, italics are displayed. If not? No
italics.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Comparing Swagger with Thrift or gRPC</title>
      <link>https://sookocheff.com/post/api/swagger-thrift-or-grpc/</link>
      <pubDate>Thu, 09 Feb 2017 15:46:53 +0000</pubDate>
      <guid>https://sookocheff.com/post/api/swagger-thrift-or-grpc/</guid>
      <description>&lt;p&gt;I’ve been asked recently, what’s the difference between Swagger and Thrift
(or gRPC)? Although they look similar, they solve fundamentally different
problems. Let’s look at the differences.&lt;/p&gt;
&lt;h2 id=&#34;swagger&#34;&gt;Swagger&lt;/h2&gt;
&lt;p&gt;At the most basic level, Swagger is a REST API specification language. The
great part is that there is an entire ecosystem of tools built around this
specification language to support API design, client and server code
generation, and interactive documentation.&lt;/p&gt;
&lt;h3 id=&#34;key-features&#34;&gt;Key Features&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;REST + JSON API framework.&lt;/li&gt;
&lt;li&gt;JSON requests and responses.&lt;/li&gt;
&lt;li&gt;Code generation.&lt;/li&gt;
&lt;li&gt;Documentation generation.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;thrift&#34;&gt;Thrift&lt;/h2&gt;
&lt;p&gt;Thrift is a software framework for supporting RPC. An interface definition
language is used to describe your system in terms of data types and
interfaces, the Thrift compiler generates client and server code that
match your definition, and the Thrift library handles
serialization and transport.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Being Good Enough</title>
      <link>https://sookocheff.com/post/opinion/being-good-enough/</link>
      <pubDate>Tue, 31 Jan 2017 15:03:32 +0000</pubDate>
      <guid>https://sookocheff.com/post/opinion/being-good-enough/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Better a diamond with a flaw than a pebble without. &lt;em&gt;Confucius&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We all want to have a perfect product, a perfect system, and a perfect
development story. Unfortunately, reality is &amp;hellip; reality. And it’s not
perfect. One of the biggest struggles of engineering well is understanding
the constant push and pull among the forces that govern the “rest of the
business”, and governing your technological and development choices
accordingly.&lt;/p&gt;
&lt;p&gt;Do not strive for perfection. Strive to be &lt;em&gt;good enough&lt;/em&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Yet Another S3 Static Site</title>
      <link>https://sookocheff.com/post/aws/yet-another-s3-static-site/</link>
      <pubDate>Wed, 18 Jan 2017 11:59:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/aws/yet-another-s3-static-site/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://github.com/soofaloofa/yas3s&#34;&gt;Here it is&lt;/a&gt;. My version of the S3 static site.&lt;/p&gt;
&lt;p&gt;This one is publishable through CloudFormation and uses CodeCommit and
CodeBuild to regenerate and publish the site with every push to the host
Git repository.&lt;/p&gt;
&lt;p&gt;Any change to the CodeCommit Git repository automatically triggers a build
through CodeCommit. This build runs the Hugo static site generator on your
repo and syncs the results to an S3 bucket configured for serving a static
site.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Packaging a Custom Boomi Connector</title>
      <link>https://sookocheff.com/post/integration/packaging-a-custom-boomi-connector/</link>
      <pubDate>Tue, 17 Jan 2017 11:12:37 -0600</pubDate>
      <guid>https://sookocheff.com/post/integration/packaging-a-custom-boomi-connector/</guid>
      <description>&lt;p&gt;Having &lt;a href=&#34;https://sookocheff.com/post/integration/creating-a-custom-boomi-connector/&#34;&gt;created a custom Boomi
connector&lt;/a&gt;,
the next step is packaging it as a Jar file for testing and release. This
requires setting some configuration files that allow the Atom process to
load and run your files.&lt;/p&gt;
&lt;h2 id=&#34;connector-configuration-file&#34;&gt;Connector configuration file&lt;/h2&gt;
&lt;p&gt;The first configuration we need to set is the
&lt;code&gt;META-INF/connector-config.xml&lt;/code&gt; file. This file tells the Atom process
which class implements your custom connector. This file must have a root
XML element named &lt;code&gt;GenericConnector&lt;/code&gt; and specify the class name of your
connector — which must be the class that extends the &lt;code&gt;BaseConnector&lt;/code&gt; class.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Creating a Custom Dell Boomi Connector</title>
      <link>https://sookocheff.com/post/integration/creating-a-custom-boomi-connector/</link>
      <pubDate>Mon, 16 Jan 2017 12:37:03 -0600</pubDate>
      <guid>https://sookocheff.com/post/integration/creating-a-custom-boomi-connector/</guid>
      <description>&lt;p&gt;This article will show you how to create a custom connector for reading
data from Dell Boomi. The connector will read the list of GitHub
follower’s from the public GitHub API. This should provide an overview of
how to write your own custom connector for a unique I/O source.&lt;/p&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;To follow along, you need to have a valid Boomi licence (or free trial) to
setup the Boomi Connector SDK. The SDK is written in Java so Java
development experience is assumed.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: Implementing Data Cubes Efficiently</title>
      <link>https://sookocheff.com/post/databases/implementing-data-cubes-efficiently/</link>
      <pubDate>Sat, 14 Jan 2017 08:21:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/implementing-data-cubes-efficiently/</guid>
      <description>&lt;p&gt;Business intelligence and analytics use cases involve complex queries on
potentially very large databases. To minimize query response times, query
optimization is critical. One approach to optimizing query response times
is to precompute relevant values ahead of time, and to use those
precomputed results to answer queries. Unfortunately, it is not always
feasible to precompute every potential value that is required to answer
arbitrary queries. This paper describes a framework and presents
algorithms that pick a good subset of queries to precompute to optimize
response time.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Getting Started With Dell Boomi</title>
      <link>https://sookocheff.com/post/integration/getting-started-with-dell-boomi/</link>
      <pubDate>Wed, 11 Jan 2017 09:24:21 -0600</pubDate>
      <guid>https://sookocheff.com/post/integration/getting-started-with-dell-boomi/</guid>
      <description>&lt;p&gt;This tutorial describes how to setup a test integration running Dell Boomi.
For those not familiar, Boomi is an integration platform as a service that
implements many of the integration patterns described in the book
&lt;a href=&#34;http://www.enterpriseintegrationpatterns.com/&#34;&gt;Enterprise Integration
Patterns&lt;/a&gt;. It is
a commercial alternative to the &lt;a href=&#34;http://camel.apache.org/&#34;&gt;Apache Camel&lt;/a&gt;
open source integration framework.&lt;/p&gt;
&lt;h2 id=&#34;boomi-overview&#34;&gt;Boomi Overview&lt;/h2&gt;
&lt;p&gt;Boomi allows developers to run an integration &lt;em&gt;Process&lt;/em&gt;, which is composed
of an input stage, followed by data transformations and any business
logic, followed by one or more output stages where the data is written out
to a final destination.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Optimistic Locking in a REST API</title>
      <link>https://sookocheff.com/post/api/optimistic-locking-in-a-rest-api/</link>
      <pubDate>Wed, 21 Dec 2016 14:32:35 +0000</pubDate>
      <guid>https://sookocheff.com/post/api/optimistic-locking-in-a-rest-api/</guid>
      <description>&lt;p&gt;In a REST application, it’s often the case that several clients might
interact with a single resource, each holding a copy of the resources
state. At any point in time, these client’s understanding of resource
state may differ from each other or from the server. Without some way of
realigning resource state, changes requested by a client based on an
out-of-date understanding of resource may have undesired effects, from
repeating computationally expensive requests to overwriting and losing
another client’s changes.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Checking for null in an API Gateway transform</title>
      <link>https://sookocheff.com/post/api/checking-for-null-in-api-gateway/</link>
      <pubDate>Mon, 19 Dec 2016 15:14:35 +0000</pubDate>
      <guid>https://sookocheff.com/post/api/checking-for-null-in-api-gateway/</guid>
      <description>&lt;p&gt;Amazon’s &lt;a href=&#34;https://aws.amazon.com/documentation/apigateway/&#34;&gt;API Gateway&lt;/a&gt;
provides the ability to transform a response from an endpoint into
a different format for return to the client.&lt;/p&gt;
&lt;p&gt;One thing I wished to accomplish with this was to return a value to the
client, only if it was set in the response. Essentially, I wanted to check
for the existence of a JSON property in the response, and react
accordingly. The solution was not obvious to me, and this post serves to
record that solution for posterity.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Effective Cache Control</title>
      <link>https://sookocheff.com/post/api/effective-caching/</link>
      <pubDate>Mon, 19 Dec 2016 15:10:35 +0000</pubDate>
      <guid>https://sookocheff.com/post/api/effective-caching/</guid>
      <description>&lt;p&gt;The web supports a global network of billions of devices and users, and
a key component of this support is effectively caching frequently accessed
data along the request-response path. One of the key benefits in adopting
a REST architectural style for your system is being able to leverage this
existing infrastructure, taking advantage of the billions of dollars of
investment already made in the web, and promoting loose coupling,
performance and scalability.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Configuring REST-assured for Amazon API Gateway</title>
      <link>https://sookocheff.com/post/api/rest-assured-tests-against-api-gateway/</link>
      <pubDate>Tue, 13 Dec 2016 12:21:53 +0000</pubDate>
      <guid>https://sookocheff.com/post/api/rest-assured-tests-against-api-gateway/</guid>
      <description>&lt;p&gt;As part of testing our Amazon API Gateway deployment, we set up JUnit
tests to run automated Swagger/OpenAPI validation using &lt;a href=&#34;https://bitbucket.org/atlassian/swagger-request-validator&#34;&gt;Swagger
Request
Validator&lt;/a&gt; and
&lt;a href=&#34;http://rest-assured.io/&#34;&gt;REST-assured&lt;/a&gt;. This allows us to write simple
tests in a fluent style, with automatic validation that requests and
responses match the Swagger API specification deployed to API Gateway.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;given&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;all&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;filter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;validationFilter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;when&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;post&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;/oauth2/token&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;then&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;assertThat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;statusCode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Out of the box, REST-assured does not work with Amazon’s API Gateway
endpoints using Java 8. Attempting to use it results in a handshake error
when connecting to the API Gateway endpoint.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: Robust Query Processing through Progressive Optimization</title>
      <link>https://sookocheff.com/post/databases/pop/</link>
      <pubDate>Fri, 18 Nov 2016 09:58:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/pop/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=4929312332613352080&#34;&gt;Robust Query Processing through Progressive
Optimization&lt;/a&gt;.
Markl et al.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Traditional query optimizers choose an execution plan for a query by using
estimates of current database statistics. However, these estimates may be
inaccurate, leading to overly expensive query plans being chosen and
executed. This paper presents progressive query optimization, allowing
query execution to detect and recover from estimation errors during
processing.&lt;/p&gt;
&lt;p&gt;During each execution step, progressive query optimization (POP) detects
differences between the cardinality of the currently processed tuple and
compares that to the estimated cardinality that was used to define the
original execution plan. If those cardinalities differ enough, POP will
re-optimize the query using updated estimates of cardinality. Any
materialized views already computed can be reused during the re-execution
step.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Creating a Service Oriented Organization</title>
      <link>https://sookocheff.com/post/architecture/creating-a-service-oriented-organization/</link>
      <pubDate>Sun, 30 Oct 2016 21:59:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/creating-a-service-oriented-organization/</guid>
      <description>&lt;p&gt;The decision to build products using a service-oriented (or microservice)
architecture has enormous technical and organizational impact that is reflected
in everything from how teams write code, to how they communicate, to how the
organization itself is structured. Given the breadth and depth of impact this
decision has, it pays to reflect on &lt;em&gt;why&lt;/em&gt; an organization chooses a service
oriented architecture, &lt;em&gt;how&lt;/em&gt; an organization can support such an architecture,
and how teams and individuals can &lt;em&gt;support the organization&lt;/em&gt; in successfully
adopting a service oriented platform.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Understanding API Gateway Payload Mappings</title>
      <link>https://sookocheff.com/post/api/understanding-api-gateway-payload-mappings/</link>
      <pubDate>Fri, 21 Oct 2016 09:41:35 +0000</pubDate>
      <guid>https://sookocheff.com/post/api/understanding-api-gateway-payload-mappings/</guid>
      <description>&lt;p&gt;Amazon’s API Gateway provides the facilities to map an incoming request’s
payload to match the required format of an integration backend.&lt;/p&gt;
&lt;figure&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;APIGatewayPayloadMapping.png&#34;/&gt; &lt;figcaption&gt;
            API Gateway Payload Mapping
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;API Gateway uses the concept of “models” and “mapping templates” to
specify the mapping between the client payload and the server payload.&lt;/p&gt;
&lt;h2 id=&#34;models&#34;&gt;Models&lt;/h2&gt;
&lt;p&gt;A model defines the structure of the incoming payload using &lt;a href=&#34;http://json-schema.org/&#34;&gt;JSON
Schema&lt;/a&gt;. The model is an optional, but not
required, piece of API Gateway. By providing a model, you make it easier
to define the upcoming mapping template that actually does the
transformation between the client and server.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Securing a Swagger API with OAuth2</title>
      <link>https://sookocheff.com/post/api/securing-a-swagger-api-with-oauth2/</link>
      <pubDate>Wed, 19 Oct 2016 15:46:53 +0000</pubDate>
      <guid>https://sookocheff.com/post/api/securing-a-swagger-api-with-oauth2/</guid>
      <description>&lt;p&gt;In our previous &lt;a href=&#34;https://sookocheff.com/post/api/swagger/&#34;&gt;article on Swagger&lt;/a&gt;, we defined a Player API modelling GET access to a &lt;code&gt;Player&lt;/code&gt; resource.
In this article, I show how to use Swagger’s security models to to deploy
this API using an OAuth2 configuration.&lt;/p&gt;
&lt;p&gt;Swagger handles authentication and authorization using a combination of a “Security
Definitions” Object and a list of “Security Requirements” Objects. Each of
these definitions are applied at the top-level of your Swagger
specification.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to deploy a Swagger specification to Amazon API Gateway using CloudFormation</title>
      <link>https://sookocheff.com/post/api/deploying-swagger-to-api-gateway/</link>
      <pubDate>Tue, 18 Oct 2016 10:32:35 +0000</pubDate>
      <guid>https://sookocheff.com/post/api/deploying-swagger-to-api-gateway/</guid>
      <description>&lt;p&gt;Full sample code for this article is available &lt;a href=&#34;https://github.com/soofaloofa/swagger-demo&#34;&gt;on
Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Aamazon’s API Gateway supports the direct importing of Swagger
specification files using CloudFormation rules. To do this, you have two
choices. Injecting the &lt;code&gt;swagger.json&lt;/code&gt; or &lt;code&gt;swagger.yaml&lt;/code&gt; file directly into
the &lt;code&gt;Body&lt;/code&gt; field of the CloudFormation template, or uploading the
&lt;code&gt;swagger.json&lt;/code&gt; or &lt;code&gt;swagger.yaml&lt;/code&gt; file to an S3 location and setting that
location as the &lt;code&gt;BodyS3Location&lt;/code&gt; field of the CloudFormation template.&lt;/p&gt;
&lt;p&gt;A minimal YAML template is listed below:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Designing a Swagger API</title>
      <link>https://sookocheff.com/post/api/swagger/</link>
      <pubDate>Wed, 12 Oct 2016 15:46:53 +0000</pubDate>
      <guid>https://sookocheff.com/post/api/swagger/</guid>
      <description>&lt;p&gt;The goal of &lt;a href=&#34;http://swagger.io&#34;&gt;Swagger&lt;/a&gt; is to define a standard interface
for describing REST APIs. In an ideal world, a Swagger definition for your
API will allow both humans and computers to discover and understand your
API. At it’s core, Swagger is a formal specification of an API.
Surrounding this specification are a wide swath of tools to support
creating documentation, providing client libraries, and managing API
deployments.&lt;/p&gt;
&lt;p&gt;One of Swagger’s original goal was to provide a way to document an API in
both a &lt;em&gt;human&lt;/em&gt; and &lt;em&gt;machine&lt;/em&gt; readable way. Swagger provides such
a documentation format for RESTful APIs. By augmenting this documentation
format with tools for API clients and developers, Swagger grew into an
ecosystem providing for API developers and consumers.&lt;/p&gt;</description>
    </item>
    <item>
      <title>What is OSGi? Microservices for the JVM</title>
      <link>https://sookocheff.com/post/java/what-is-osgi/</link>
      <pubDate>Tue, 11 Oct 2016 11:34:28 -0600</pubDate>
      <guid>https://sookocheff.com/post/java/what-is-osgi/</guid>
      <description>&lt;p&gt;As someone who is being recently re-introduced to the Java platform, there
are a lot of components and pieces to become familiar with. One of those
pieces is OSGi, a service registry and deployment specification for Java
apps.&lt;/p&gt;
&lt;p&gt;The OSGi specification describes a complete environment for running Java
applications as components. Each component is a bundle that can be
remotely installed, started, stopped, updated or uninstalled. In addition,
OSGi provides a service registry that allows existing services to detect
the addition or removal of other services and adapt accordingly.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: The Volcano Optimizer Generator: Extensibility and Efficient Search</title>
      <link>https://sookocheff.com/post/databases/volcano/</link>
      <pubDate>Tue, 11 Oct 2016 09:34:37 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/volcano/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=2304531151126477511&#34;&gt;The Volcano Optimizer Generator: Extensibility and Efficient
Search&lt;/a&gt;.
Goetz Graefe and William J. McKenna.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;The query optimizer’s job is to take user input in the form of SQL and
generate a cost-efficient plan for satisfying that query using the
underlying physical layout of the database. This paper describes
&lt;em&gt;Volcano&lt;/em&gt;, a system for taking a data model, logical algebra, physical
algebra, and optimization rules and translating them into optimizer source
code.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: Dynamo: Amazon’s Highly Available Key-value Store</title>
      <link>https://sookocheff.com/post/databases/dynamo/</link>
      <pubDate>Fri, 07 Oct 2016 10:59:32 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/dynamo/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=5432858092023181552&#34;&gt;Dynamo: Amazon’s Highly Available Key-value Store&lt;/a&gt;, DeCandia et al.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Dynamo, as the title of the paper suggests, is Amazon’s highly available
key-value storage system. Dynamo only supports primary-key access to data,
which is useful for services such as shopping carts and session
management. Dynamo’s use case for these services is providing
a highly-available system that always accepts writes. This requirement
forces the complexity of conflict resolution to data readers. Writes are
never rejected.&lt;/p&gt;</description>
    </item>
    <item>
      <title>0 to Message in 60 Seconds: Getting Started with Amazon SQS</title>
      <link>https://sookocheff.com/post/messaging/getting-started-with-sqs/</link>
      <pubDate>Wed, 05 Oct 2016 18:29:21 +0000</pubDate>
      <guid>https://sookocheff.com/post/messaging/getting-started-with-sqs/</guid>
      <description>&lt;p&gt;Amazon Simple Queue Service (SQS) is a message queue service that allows
applications to reliably queue messages from one system component to be
consumed by another component. Adding a queue between application
components allows them to run independently, effectively decoupling
applications by providing a buffer between producers of data and their
consumers.&lt;/p&gt;
&lt;h2 id=&#34;up-and-running&#34;&gt;Up and Running&lt;/h2&gt;
&lt;p&gt;This section provides a guide to getting up and running with SQS using
a fictional music store as an example. This music store has the ability to
notify clients of any upcoming events via SQS.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: Cap Twelve Years Later: How the “Rules” Have Changed</title>
      <link>https://sookocheff.com/post/databases/cap-twelve-years-later/</link>
      <pubDate>Wed, 05 Oct 2016 06:07:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/cap-twelve-years-later/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=17642052422667212790&#34;&gt;Cap Twelve Years Later: How the “Rules” Have Changed&lt;/a&gt;.
Eric Brewer.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;This article provides an exploration of the CAP Theorem and how it relates
to database system design. The author argues that, since partitions are
likely to happen, the system designer can introduce methods for safely
recovering from partitions to compensate. This strategy allows the
database to continue to provide availability during a partition, and
enforce consistency once the partition is resolved.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Integrating Applications: From RPC to Messaging</title>
      <link>https://sookocheff.com/post/messaging/integrating-applications-with-messaging/</link>
      <pubDate>Tue, 04 Oct 2016 11:06:57 +0000</pubDate>
      <guid>https://sookocheff.com/post/messaging/integrating-applications-with-messaging/</guid>
      <description>&lt;p&gt;When integrating two independent services you have two options: making
a remote procedure call (RPC), or sending a message. Which should you
choose?&lt;/p&gt;
&lt;h2 id=&#34;what-is-a-remote-procedure-call&#34;&gt;What is a Remote Procedure Call?&lt;/h2&gt;
&lt;p&gt;An organization often needs to share data and processes between multiple
independent processes in a responsive way. For example, updating a user’s
name in a shipping system may trigger updates in a billing system. The
shipping system could update the billing system’s data directly by
modifying a shared database, but this approach requires the shipping
system to know far too much about the internal processes of the billing
system. Instead, the business system can encapsulate the update operation
behind an interface in the form of a remote procedure call, or RPC.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Integrating Applications</title>
      <link>https://sookocheff.com/post/architecture/integrating-applications/</link>
      <pubDate>Sun, 25 Sep 2016 14:03:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/integrating-applications/</guid>
      <description>&lt;p&gt;A big portion of any software engineering revolves around integrating
multiple, disparate applications into a cohesive and functional whole.
These apps may be built in house or third-party, or they may run on your
network or distributed geographically, or they may be microservices
designed to integrate. In any of these cases, you have several different
options for integration, each with pros and cons.&lt;/p&gt;
&lt;p&gt;The integration patterns listed here are ordered by least to most
sophisticated, but also by least to most complex.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Tests are Never Enough</title>
      <link>https://sookocheff.com/post/mdd/tests-are-never-enough/</link>
      <pubDate>Fri, 23 Sep 2016 11:35:57 +0000</pubDate>
      <guid>https://sookocheff.com/post/mdd/tests-are-never-enough/</guid>
      <description>&lt;p&gt;The request was fairly simple — iterate through some data and update some
dates. Something as simple as this.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;entry&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;entry&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;date&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;entry&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;date&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;timedelta&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;days&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;entry&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;put&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Unfortunately, the NoSQL database we were using did not support schemas
and, unbeknownst to me, some data had been changed in unexpected ways on
production. Something as simple as this.&lt;/p&gt;
&lt;figure&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;InvalidDate.png&#34;/&gt; &lt;figcaption&gt;
            Notice the Outlier?
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;My code seemed correct. Unit tests passed. Code review passed. It ran
flawlessly on the test environment. QA signed off on the change. So we
deployed it. And things broke.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Problem with Point to Point Communication</title>
      <link>https://sookocheff.com/post/architecture/problem-with-point-to-point-communication/</link>
      <pubDate>Wed, 31 Aug 2016 19:40:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/problem-with-point-to-point-communication/</guid>
      <description>&lt;p&gt;Point-to-point communication between servers usually works just fine when
one or two instances are communicating.&lt;/p&gt;
&lt;figure&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;small.png&#34;/&gt; &lt;figcaption&gt;
            One or two instances communicating
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;However, if you increase the number of applications, the total number of
connections increases.&lt;/p&gt;
&lt;figure&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;medium.png&#34;/&gt; &lt;figcaption&gt;
            Three instances communicating
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;In fact, the total number of connections increases as a square of the
number of application instances. So, if you are running 100 instances, you
will be maintaining O(100^2) connections. The scaling becomes quite
painful.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Guided Tour Through Thrift</title>
      <link>https://sookocheff.com/post/thrift/a-tour-through-thrift/</link>
      <pubDate>Tue, 23 Aug 2016 08:12:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/thrift/a-tour-through-thrift/</guid>
      <description>&lt;p&gt;After reading the &lt;a href=&#34;https://thrift.apache.org/static/files/thrift-20070401.pdf&#34;&gt;Thrift
whitepaper&lt;/a&gt;
and &lt;a href=&#34;http://sookocheff.com/post/thrift/so-you-want-to-use-thrift/&#34;&gt;sending your first
message&lt;/a&gt;,
you may still have some questions about how Thrift actually works. This
article helps answer those questions by providing a guided tour through
the &lt;a href=&#34;https://thrift.apache.org/&#34;&gt;Apache Thrift&lt;/a&gt; architecture, highlighting
the protocols, transports, and compiler, and how they interact with each
other.&lt;/p&gt;
&lt;h2 id=&#34;thrift-from-10000-feet&#34;&gt;Thrift from 10,000 feet&lt;/h2&gt;
&lt;p&gt;At a high-level, Thrift is organized into several layers as in Figure 1.
The layers highlighted in yellow represent application code that is
written by a user. The portions in red represent code generated by the
Thrift compiler from an interface definition defined in an IDL file. The
layers in orange are portions of Thrift available as library code imported
into your application as a dependency. Lastly, the device layer in blue
represents the physical device transmitting messages.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Stability Anti-Patterns</title>
      <link>https://sookocheff.com/post/architecture/stability-antipatterns/</link>
      <pubDate>Mon, 15 Aug 2016 19:40:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/stability-antipatterns/</guid>
      <description>&lt;p&gt;I recently finished reading the excellent book “&lt;a href=&#34;https://pragprog.com/book/mnee/release-it&#34;&gt;Release
It!&lt;/a&gt;” by Michael Nygard. One of
the key points that I wanted to remember was the stability anti-patterns.
So, this post will serve as a reminder of architectural smells to look out
for when designing production systems.&lt;/p&gt;
&lt;p&gt;This list of anti-patterns are common forces that will create or
accelerate failures in production systems. Given the nature of distributed
systems, avoiding these patterns is not possible. You must accept that
they will happen, and program your application to be resilient to these
failures.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Metrics-Driven Development</title>
      <link>https://sookocheff.com/post/mdd/mdd/</link>
      <pubDate>Tue, 09 Aug 2016 12:14:57 +0000</pubDate>
      <guid>https://sookocheff.com/post/mdd/mdd/</guid>
      <description>&lt;p&gt;Metrics-Driven Development is an emerging term developing from the
practices of continuous integration, continuous delivery, dev ops, and
agile software methodologies. This article serves to define what
metrics-driven development is, why it is useful, and how to use it to
drive software changes.&lt;/p&gt;
&lt;p&gt;Let’s start with a definition of &lt;a href=&#34;http://blog.librato.com/posts/2014/7/16/metrics-driven-development&#34;&gt;metrics-driven
development&lt;/a&gt;.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Metrics-Driven Development (MDD)&lt;/dt&gt;
&lt;dd&gt;The use of real-time metrics to drive rapid, precise,
and granular software iterations.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;This definition is simple and straightforward, but does leave room for
interpretation. Let’s dive deeper and break the definition down,
bit-by-bit.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Testing a Producer-Consumer Design using a CyclicBarrier</title>
      <link>https://sookocheff.com/post/java/testing-producer-consumers-with-cyclic-barrier/</link>
      <pubDate>Thu, 21 Jul 2016 13:57:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/java/testing-producer-consumers-with-cyclic-barrier/</guid>
      <description>&lt;p&gt;Testing concurrent objects can be challenging. One particular pattern that
is useful for objects used in producer-consumer designs is to ensure that
everything put in to a shared concurrent queue by a producer is correctly
executed by consumers.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: Generalized Isolation Level Definitions</title>
      <link>https://sookocheff.com/post/databases/generalized-isolation-level-definitions/</link>
      <pubDate>Thu, 23 Jun 2016 06:00:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/generalized-isolation-level-definitions/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=12975897967422539576&#34;&gt;Generalized Isolation Level
Definitions&lt;/a&gt;,
Adya et al.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;The ANSI SQL standard defines isolation levels allowing database users to
trade off between performance and consistency when running transactions.
Unfortunately, the wording in the SQL standard is geared towards locking
as the sole supported concurrency method. This paper presents alternative
definitions to the isolation levels specified in the ANSI SQL standard
that are general enough to allow for any concurrency method
(multi-version, optimistic, etc.) to be used.&lt;/p&gt;</description>
    </item>
    <item>
      <title>So you want to send a message using Apache Thrift?</title>
      <link>https://sookocheff.com/post/thrift/so-you-want-to-use-thrift/</link>
      <pubDate>Fri, 17 Jun 2016 15:32:37 -0600</pubDate>
      <guid>https://sookocheff.com/post/thrift/so-you-want-to-use-thrift/</guid>
      <description>&lt;h1 id=&#34;so-you-want-to-use-thrift&#34;&gt;So you want to use Thrift?&lt;/h1&gt;
&lt;p&gt;You’ve come here because you want to use &lt;a href=&#34;https://thrift.apache.org/&#34;&gt;Apache
Thrift&lt;/a&gt; and you don’t know where to start.
Good. You&amp;rsquo;re in the right spot.&lt;/p&gt;
&lt;p&gt;Throughout this document we will develop a simple service that
communicates using Thrift. This will introduce you to the workflow for
generating client and server code using Thrift and how to Thrift works to
separate your application’s business logic from it’s transport methods.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: DryadLINQ: A System for General-Purpose Distributed Data-Parallel Computing Using a High-Level Language</title>
      <link>https://sookocheff.com/post/databases/dryadlinq/</link>
      <pubDate>Thu, 09 Jun 2016 15:56:11 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/dryadlinq/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=3662601067977846800&#34;&gt;DryadLINQ: A System for General-Purpose Distributed Data-Parallel Computing Using a High-Level Language&lt;/a&gt;, Yu et al.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;DryadLINQ describes a system for distributing the computation of &lt;a href=&#34;https://msdn.microsoft.com/en-us/library/bb397926.aspx&#34;&gt;.NET
LINQ expressions&lt;/a&gt;
on an underlying &lt;a href=&#34;http://research.microsoft.com/en-us/projects/dryad/&#34;&gt;Dryad
cluster&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The motivation for this work is to simplify the expression of data
parallel algorithms by providing using the higher-level LINQ primitives.
This allows the programmer to implement their algorithm as if it was
computed on a single machine, and allow the system to worry about the
complexities of scheduling, distribution, and fault-tolerance.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: MapReduce: Simplified Data Processing on Large Clusters</title>
      <link>https://sookocheff.com/post/databases/mapreduce/</link>
      <pubDate>Wed, 08 Jun 2016 07:55:13 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/mapreduce/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;MapReduce: Simplified Data Processing on Large Clusters, &lt;a href=&#34;https://scholar.google.com/scholar?cluster=10940266603640308767&#34;&gt;Jeffrey Dean and
Sanjay Ghemawat&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;MapReduce is designed to solve the problem of processing large sets of
data on a fleet of commodity hardware. In such an environment it is
assumed that you may have hundreds or thousands of machines and that, at
any point in time, these machines may experience failures.&lt;/p&gt;
&lt;p&gt;The MapReduce framework hides the details of parallelizing your workflow,
fault-tolerance, distributing data to workers, and load balancing behind
the abstractions &lt;em&gt;map&lt;/em&gt; and &lt;em&gt;reduce&lt;/em&gt;. The user of MapReduce is responsible
for writing these map and reduce functions, while the MapReduce library is
responsible for executing that program in a distributed environment.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: OLTP Through the Looking Glass, and What We Found There</title>
      <link>https://sookocheff.com/post/databases/oltp-through-the-looking-glass/</link>
      <pubDate>Mon, 06 Jun 2016 09:58:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/oltp-through-the-looking-glass/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=12931776946707721868&#34;&gt;OLTP Through the Looking Glass, and What We Found
There&lt;/a&gt;,
Harizopoulos et al.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Disk I/O has been the primary limiting factor in database performance for
most commercial databases. However, as prices of main-memory have dropped
it has become feasible to keep the entire working set of a database in
RAM. With this architectural change, it makes sense to evaluate database
design decisions made to avoid disk I/O to see which ones still hold
promise in a main-memory world. This paper provides such a performance
analysis.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Getting Started with Amazon Flow Framework</title>
      <link>https://sookocheff.com/post/aws/getting-started-with-flow-framework/</link>
      <pubDate>Thu, 02 Jun 2016 11:59:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/aws/getting-started-with-flow-framework/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://aws.amazon.com/swf/details/flow/&#34;&gt;Amazon’s Flow Framework&lt;/a&gt;
provides a high-level SDK for interacting with the &lt;a href=&#34;https://aws.amazon.com/swf/&#34;&gt;Amazon Simple Workflow
service&lt;/a&gt; (SWF). SWF is a managed service that
helps developers build, run and monitor parallel or sequential
asynchronous workloads. SWF reliably commits your workflow’s state to
durable storage, allowing you to focus on your business logic rather than
on the complex coordination of distributed services.&lt;/p&gt;
&lt;p&gt;Writing an application with the flow framework can be divided into the
following steps:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: Hekaton: SQL Server’s Memory-Optimized OLTP Engine</title>
      <link>https://sookocheff.com/post/databases/hekaton/</link>
      <pubDate>Fri, 27 May 2016 06:00:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/hekaton/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=14161764654889427045&#34;&gt;Hekaton: SQL Server’s Memory-Optimized OLTP
Engine&lt;/a&gt;,
Diaconu et al.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Database design has traditionally revolved around efficient access to
disk. However, recent memory prices make it feasible to keep the majority
(or entirety) of a database in main-memory. A main-memory design requires
a few adjustments to maximize concurrency, handle transactions, and
recover after failure. This paper describes such a design in relation to
the development of &lt;em&gt;Hekaton&lt;/em&gt; — an extension to Microsoft’s SQL Server.
With Hekaton, if the user specifies that a table is “memory-optimized”,
this triggers SQL Server to store that table entirely in memory, allowing
Hekaton to optimize the table with its in-memory database engine.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: C-Store: A column-oriented DBMS</title>
      <link>https://sookocheff.com/post/databases/c-store/</link>
      <pubDate>Wed, 25 May 2016 06:07:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/c-store/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=12924804892742402591&#34;&gt;C-Store: A column-oriented
DBMS&lt;/a&gt;.
Stonebraker et al.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;In traditional databases, all attributes of a record (or tuple) are stored
together as a contiguous block. When writing to disk, a single write
pushes all fields of the record to disk. For the purposes of this paper,
we call this type of DBMS a &lt;em&gt;write-optimized&lt;/em&gt; system and this type of
system works well for transactional processing. However, for querying data
we can do better with a system that is &lt;em&gt;read-optimized&lt;/em&gt;. C-Store is such
a read-optimized system.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Concurrency: A Primer</title>
      <link>https://sookocheff.com/post/concurrency/concurrency-a-primer/</link>
      <pubDate>Tue, 17 May 2016 15:39:37 -0600</pubDate>
      <guid>https://sookocheff.com/post/concurrency/concurrency-a-primer/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Writing correct programs is hard; writing correct concurrent programs is
harder. &lt;em&gt;&lt;a href=&#34;http://jcip.net&#34; title=&#34;Java Concurrency in Practice&#34;&gt;Java Concurrency in Practice&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, why bother with concurrency? A number of reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Concurrency provides a natural method for composing asynchronous code.&lt;/li&gt;
&lt;li&gt;Concurrency allows your program to avoid blocking user operations.&lt;/li&gt;
&lt;li&gt;Concurrency provides one of the easiest ways take advantage of multi core systems.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As processor counts increase, exploiting concurrency will be an even more
important facet of high performance systems. Yet, before diving in to
writing a concurrent program, it pays to understand the fundamentals of
concurrency. To aid in such understanding, this article will provide
background material on concurrency and an exploration of different methods
for managing state and different models for writing concurrent program.
The article is split into three main sections:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Server-to-server OAuth with the Google OAuth Client Library for Java</title>
      <link>https://sookocheff.com/post/oauth/server-to-server-oauth-with-java/</link>
      <pubDate>Thu, 12 May 2016 13:27:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/oauth/server-to-server-oauth-with-java/</guid>
      <description>&lt;p&gt;This post describes how to validate a JWT token using the Google OAuth
library for making server-to-server OAuth requests.&lt;/p&gt;
&lt;p&gt;First, there is a prerequisite of being able to read a key file from your
local file system. This key file is obtained from the system that you wish
to authorize against and contains the private-key pair authorizing your
server with the other system.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt; * Return private key from a file. Must be a valid PEM file with PKCS#8 encoding standard.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt; *
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt; * @return a private key
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt; */&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;PrivateKey&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;loadPrivateKey&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;File&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keyFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;throws&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IOException&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NoSuchAlgorithmException&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;InvalidKeySpecException&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;byte&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;toByteArray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keyFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PKCS8EncodedKeySpec&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ks&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PKCS8EncodedKeySpec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;KeyFactory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getInstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;RSA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;generatePrivate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, assuming we have a valid private key, authenticating with an OAuth
end-point using a JWT token is a matter of mapping the JWT token
properties with the correct GoogleCredential methods. When
GoogleCredential calls the API to obtain a new access token, it converts
the methods set on the credential to the correct JWT token properties
according to the following table.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: Transaction Management in the R Distributed Database Management System</title>
      <link>https://sookocheff.com/post/databases/distributed-transaction-management/</link>
      <pubDate>Fri, 06 May 2016 09:54:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/distributed-transaction-management/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=6135007404184895390&#34;&gt;Transaction Management in the R Distributed Database Management System&lt;/a&gt;. C. Mohan et al.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;This paper describes to handle transactions in a distributed environment using
a &lt;a href=&#34;thttps://en.wikipedia.org/wiki/Two-phase_commit_protocol&#34;&gt;two-phase commit protocol
(2PC)&lt;/a&gt;. 2PC is a form
of atomic commit that uses a coordinator to decide whether or not to commit or
abort a transaction. The paper goes on to compare &lt;em&gt;standard&lt;/em&gt; 2PC with two
variations (1) &lt;em&gt;presumed abort (PA)&lt;/em&gt; and (2) &lt;em&gt;presumed commit (PC)&lt;/em&gt;, which
differ in how they handle failure conditions. This paper review will be divided
into three sections, one for 2PC, one for PA, and one for PC.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: Concurrency Control Performance Modeling: Alternatives and Implications</title>
      <link>https://sookocheff.com/post/databases/concurrency-performance-modeling/</link>
      <pubDate>Mon, 25 Apr 2016 06:00:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/concurrency-performance-modeling/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=9784855600346107276&#34;&gt;Concurrency Control Performance Modeling: Alternatives and
Implications&lt;/a&gt;.
R. Agrawal et al.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;This paper takes an in-depth look at the performance implications of
varying concurrency control algorithms. Specifically, it examines the
performance of three concurrency methods: &lt;em&gt;blocking&lt;/em&gt;, &lt;em&gt;immediate-restart&lt;/em&gt;,
and &lt;em&gt;optimistic&lt;/em&gt;. In the &lt;em&gt;blocking&lt;/em&gt; algorithm, all transactions set locks on
objects that are read or written; whenever a lock request is denied, the
requesting transaction is placed in a waiting queue until it can proceed
(on deadlock, the youngest transaction is restarted). With
&lt;em&gt;immediate-restart&lt;/em&gt; transactions again acquire locks on objects. In this
case, however, if the transaction is blocked it is immediately restarted
(with some delay). For the &lt;em&gt;optimistic&lt;/em&gt; case, all transactions are allowed
to proceed as if no conflicts occur; only if a conflict is detected at
commit time is a transaction restarted.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: Granularity of Locks and Degrees of Consistency in a Shared Data Base</title>
      <link>https://sookocheff.com/post/databases/locks-and-consistency/</link>
      <pubDate>Tue, 19 Apr 2016 06:00:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/locks-and-consistency/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=15730220590995320737&#34;&gt;Granularity of Locks and Degrees of Consistency in a Shared Data
Base&lt;/a&gt;. J.
Gray et al.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;This paper is divided in two sections: granularity of locks, and degrees
of consistency. Each section answers questions on how lock choice in
a database affects throughput and consistency.&lt;/p&gt;
&lt;h3 id=&#34;granularity-of-locks&#34;&gt;Granularity of Locks&lt;/h3&gt;
&lt;p&gt;In the granularity section, the choice of &lt;em&gt;lockable units&lt;/em&gt; is discussed.
A lockable unit represents a section of logical data that is atomically
locked during a transaction. Locking smaller units such as individual
records improves concurrency for “simple” transactions that access a small
number of records. On the other hand, locking at a record level can reduce
throughput for “complex” transactions that require access to many records
— the overhead of acquiring and releasing locks overwhelms the
computation. It follows that having different sizes of lockable units in
the same system is required to handle multiple use cases.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: ARIES: a transaction recovery method supporting fine-granularity locking and partial rollbacks using write-ahead logging</title>
      <link>https://sookocheff.com/post/databases/aries/</link>
      <pubDate>Wed, 30 Mar 2016 19:14:23 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/aries/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=2142924814045750364&#34;&gt;ARIES: a transaction recovery method supporting fine-granularity locking
and partial rollbacks using write-ahead
logging&lt;/a&gt;.
C. Mohan et al.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;ARIES presents and validates the concept of &lt;a href=&#34;https://en.wikipedia.org/wiki/Write-ahead_logging&#34;&gt;write-ahead
logging&lt;/a&gt;, providing
industrial strength support for atomicity and durability. As described in
the &lt;a href=&#34;http://www.redbook.io&#34;&gt;Red Book&lt;/a&gt;, write-ahead logging is
a “near-ubiquitous technique for maintaining durability”. ARIES provides
the reference implementation for “No Force, Steal” write-ahead logging
used by most databases today. With a “No Force” policy, transactions can
be committed without actually flushing dirty pages to disk, while
a “Steal” policy implies dirty pages can be flushed to disk at any time.
Combined, these two policies allow for high performance as the current
state of pages in the database can be kept in memory, avoiding unnecessary
I/O operations.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Deploying a static website with rsync</title>
      <link>https://sookocheff.com/post/linux/deploying-a-static-site-with-rsync/</link>
      <pubDate>Tue, 29 Mar 2016 06:00:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/linux/deploying-a-static-site-with-rsync/</guid>
      <description>&lt;p&gt;This is one of those things that we all kinda know but that it’s good to
write down – how to deploy static files using rsync. For purposes of
illustration, this article will describe how to deploy a statically
generated website.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Thoughts On Google Cloud Platform Next</title>
      <link>https://sookocheff.com/post/opinion/thoughts-on-gcp-next-2016/</link>
      <pubDate>Mon, 28 Mar 2016 15:20:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/opinion/thoughts-on-gcp-next-2016/</guid>
      <description>&lt;p&gt;I was fortunate enough to attend Google Cloud Platform Next last week and
wanted to summarize a few of my thoughts on the conference. As I sat down
to analyze the event, I found a few distinct themes that I would like to
expand on.&lt;/p&gt;
&lt;h2 id=&#34;multi-cloud&#34;&gt;Multi-Cloud&lt;/h2&gt;
&lt;p&gt;Google is serious about multi-cloud support for their monitoring and
integration products. As a cynic, if Google wants to steal customers from
Amazon, offering tools to aid the transition is in their best interest. As
a realist, most companies will continue to operate in a multi-cloud
environment to take advantage of the strengths of each platform, and it’s
nice to see Google recognizing this fact and working within it. Either
way, I think being open about supporting AWS is a good thing.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: Access Path Selection in a Relational Database Management System</title>
      <link>https://sookocheff.com/post/databases/access-path-selection-in-a-rdbms/</link>
      <pubDate>Tue, 15 Mar 2016 06:00:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/access-path-selection-in-a-rdbms/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=102545501597608314&#34;&gt;Access Path Selection in a Relational Database Management
System&lt;/a&gt;. P.
G. Selinger et al.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;This paper describes methods of the SQL query optimizer for determining
the cost of satisfying a query. It also describes methods for choosing
among several competing methods.&lt;/p&gt;
&lt;h2 id=&#34;what-are-the-motivations-for-this-work&#34;&gt;What are the motivations for this work?&lt;/h2&gt;
&lt;p&gt;SQL is a high-level language where requests for data are stated
non-procedurally. The user is not expected to need any knowledge of how
the data is stored in the database or how it is retrieved. Thus, it is up
to the DBMS to choose an appropriate access path for data retrieval on the
users behalf. By designing the database in this fashion, we preserve &lt;em&gt;data
independence&lt;/em&gt;, where a users view of the data is independent of the
databases view of the data.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: Eddies: Continuously Adaptive Query Processing</title>
      <link>https://sookocheff.com/post/databases/eddies/</link>
      <pubDate>Tue, 15 Mar 2016 06:00:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/eddies/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=13049208738754012194&#34;&gt;Eddies: Continuously Adaptive Query Processing&lt;/a&gt;.
Ron Avnur and Joseph M. Hellerstein.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Eddies describes a query optimization system that continuously reorders
operators in a query plan as the it runs. This insight is based on the
observation that assumptions made about the database at the time that
a query is submitted will rarely hold throughout the duration of query
processing.&lt;/p&gt;
&lt;p&gt;Query plans can be reordered using two criteria: &lt;em&gt;synchronization
barriers&lt;/em&gt; and &lt;em&gt;moments of symmetry&lt;/em&gt;. Synchronization barriers exist
whenever an operator is waiting for a table scan to complete before making
forward progress. In general, these barriers limit concurrency and one
goal of the eddies system is to avoid or improve these barriers by
selecting an appropriate join algorithm.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: The Gamma Database Machine Project</title>
      <link>https://sookocheff.com/post/databases/gamma-database-machine/</link>
      <pubDate>Wed, 09 Mar 2016 06:00:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/gamma-database-machine/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=8912521541627865753&#34;&gt;The Gamma Database Machine Project&lt;/a&gt;.
David J. DeWitt et al.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;This paper presents the research undertaken at the University of
Wisconsin-Madison to develop a scalable database architecture. The paper
presents novel methods for scaling a database cluster using
a &lt;a href=&#34;https://scholar.google.ca/scholar?q=Stonebraker+The+case+for+shared+nothing&amp;amp;btnG=&amp;amp;hl=en&amp;amp;as_sdt=0%2C5&#34;&gt;shared-nothing
architecture&lt;/a&gt;,
and for using hash-based join algorithms to parallelize the workload
across the cluster.&lt;/p&gt;
&lt;h2 id=&#34;what-are-the-motivations-for-this-work&#34;&gt;What are the motivations for this work?&lt;/h2&gt;
&lt;p&gt;The motivation behind Gamma was to support horizontally scalable database
using commodity parts.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Local Development with the Kinesis Client Library</title>
      <link>https://sookocheff.com/post/kinesis/local-development-with-the-kcl/</link>
      <pubDate>Fri, 04 Mar 2016 13:27:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/kinesis/local-development-with-the-kcl/</guid>
      <description>&lt;p&gt;I’ve been working on an application to read data from a Kinesis using the
&lt;a href=&#34;http://docs.aws.amazon.com/kinesis/latest/dev/kinesis-record-processor-implementation-app-java.html&#34;&gt;Kinesis Client
Library for
Java&lt;/a&gt;.
One requirement was to be able to run the application locally during
development. This requires configuring Kinesis, DynamoDB, and CloudWatch
to work locally.&lt;/p&gt;
&lt;h2 id=&#34;dynalite&#34;&gt;Dynalite&lt;/h2&gt;
&lt;p&gt;Getting a local copy of DynamoDB running is easily done using the
&lt;a href=&#34;https://github.com/mhart/dynalite&#34;&gt;dynalite&lt;/a&gt; library.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;gt; npm install -g dynalite
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;gt; dynalite --port &lt;span class=&#34;m&#34;&gt;7000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;kinesalite&#34;&gt;Kinesalite&lt;/h2&gt;
&lt;p&gt;A local copy of Kinesis is found with the
&lt;a href=&#34;https://github.com/mhart/kinesalite&#34;&gt;kinesalite&lt;/a&gt; library.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: The Design of POSTGRES</title>
      <link>https://sookocheff.com/post/databases/the-design-of-postgres/</link>
      <pubDate>Fri, 04 Mar 2016 05:42:11 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/the-design-of-postgres/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=7945977557090027847&#34;&gt;The Design of POSTGRES&lt;/a&gt;,
Michael Stonebraker and Lawrence A. Rowe.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Postgres started as a research project to extend the standard database
architecture to support several additional concepts: complex objects as
values, user-defined data types and procedures, and alerting and triggers.&lt;/p&gt;
&lt;p&gt;This paper describes the system architecture designed to achieve these
goals, while retaining functionality of the relational model. Although the
design incorporates additional ideas such as time varying data, I will
focus my review on the user-defined types and alerting scenarios.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: System R: Relational Approach to Database Management</title>
      <link>https://sookocheff.com/post/databases/system-r/</link>
      <pubDate>Wed, 02 Mar 2016 06:00:31 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/system-r/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=15466550502837111601&#34;&gt;System R: Relational Approach to Database
Management&lt;/a&gt;.
M. M. Astrahan et al.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;It’s hard to overstate the influence that the System R project had on
database design and implementation. After reading this paper it is clear
that traditional database architecture has not significantly changed since
the System R project. System R provided the first implementation of SQL,
the first demonstration of performant transactions, and provided the
foundational groundwork in concurrency control and query optimization.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Five Stages of NoSQL</title>
      <link>https://sookocheff.com/post/opinion/the-five-stages-of-nosql/</link>
      <pubDate>Sun, 28 Feb 2016 17:10:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/opinion/the-five-stages-of-nosql/</guid>
      <description>&lt;p&gt;Imagine a fledgling software startup consisting of one or two developers.
They are following the &lt;a href=&#34;http://theleanstartup.com/&#34;&gt;lean startup&lt;/a&gt;
methodology by throwing ideas and implementations at a wall to see what
sticks. This methodology demands keeping your application as simple as
possible until you find the optimum market. An on-going concern for the
developers is finding a simple, flexible way to store application data:
NoSQL or SQL?&lt;/p&gt;
&lt;p&gt;The NoSQL database offers a premium out-of-the-box experience: install
a package, start the database, and post and retrieve data using a JSON
API. And by eschewing the details of a schema and the inconvenience of
data modelling, the NoSQL database allows for fast iteration.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: Architecture of a Database System</title>
      <link>https://sookocheff.com/post/databases/architecture-of-a-database-system/</link>
      <pubDate>Wed, 24 Feb 2016 05:33:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/architecture-of-a-database-system/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=11466590537214723805&#34;&gt;Architecture of a Database
System&lt;/a&gt;. Joseph
M. Hellerstein, Michael Stonebraker, James Hamilton.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Architecture of a Database System&lt;/em&gt; provides an explanation of how to
implement a relational database. It begins with an architectural overview
of the main parts of a database system as viewed through the life of an
SQL query. This includes how the query is received, parsed and optimized
and how the resulting data is returned from storage as part of
a transaction.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Generating Java with JCodeModel</title>
      <link>https://sookocheff.com/post/java/generating-java-with-jcodemodel/</link>
      <pubDate>Sun, 21 Feb 2016 21:10:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/java/generating-java-with-jcodemodel/</guid>
      <description>&lt;p&gt;Have you come across the misfortune of needing to auto-generate Java source
code? Luckily, anything you&amp;rsquo;ve wanted to do with Java has already been done
— and auto-generating Java is no different. I recently used
&lt;a href=&#34;https://codemodel.java.net/&#34;&gt;JCodeModel&lt;/a&gt; to translate from JSON to Java — it
worked great but it lacks any tutorial-style documentation. This article means
to fill that gap. If you feel the need to go more in-depth, consult the &lt;a href=&#34;https://codemodel.java.net/nonav/apidocs/com/sun/codemodel/JCodeModel.html&#34;&gt;the
Javadoc&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Writing an Apache Beam Batch Sink</title>
      <link>https://sookocheff.com/post/beam/writing-a-beam-sink/</link>
      <pubDate>Thu, 11 Feb 2016 22:12:18 -0600</pubDate>
      <guid>https://sookocheff.com/post/beam/writing-a-beam-sink/</guid>
      <description>&lt;p&gt;This article describes how you can use the Dataflow/Beam SDK to write files to an S3
bucket by implementing a &lt;code&gt;Sink&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;Sink&lt;/code&gt; has three phases: initialization, writing, and finalization. The
initialization phase is a sequential process where you can create necessary
preconditions such as output directories. The write phase lets workers write
bundles of records to the &lt;code&gt;Sink&lt;/code&gt;. The finalization phase allows for cleanup like
merging files or committing writes.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Deploying a Druid Cluster with Ansible</title>
      <link>https://sookocheff.com/post/ansible/druid-ansible/</link>
      <pubDate>Tue, 02 Feb 2016 05:41:48 +0000</pubDate>
      <guid>https://sookocheff.com/post/ansible/druid-ansible/</guid>
      <description>&lt;p&gt;During my continued education on Ansible I&amp;rsquo;ve writing some roles for
deploying a Druid cluster to AWS similar to the article on deploying
&lt;a href=&#34;https://sookocheff.com/post/ansible/zookeeper-exhibitor-ansible/&#34;&gt;Zookeeper with Ansible&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The methods are fairly simple so rather than going through a detailed
explanation I will just leave a link to the full source
&lt;a href=&#34;https://github.com/soofaloofa/imply-ansible&#34;&gt;Github&lt;/a&gt;. Any and all
contributions are welcome!&lt;/p&gt;</description>
    </item>
    <item>
      <title>Paper Review: What Goes Around Comes Around</title>
      <link>https://sookocheff.com/post/databases/what-goes-around-comes-around/</link>
      <pubDate>Wed, 27 Jan 2016 05:21:37 -0600</pubDate>
      <guid>https://sookocheff.com/post/databases/what-goes-around-comes-around/</guid>
      <description>&lt;h2 id=&#34;title-and-author-of-paper&#34;&gt;Title and Author of Paper&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://scholar.google.com/scholar?cluster=7366182905777149494&#34;&gt;What Goes Around Comes
Around&lt;/a&gt;. Joseph
M. Hellerstein and Michael Stonebraker.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;What Goes Around Comes Around&lt;/em&gt; summarizes several methods for modelling data
within a database system. Each data model is described and the benefits and
drawbacks listed as &lt;em&gt;lessons learned&lt;/em&gt; from research into that model. The authors
clearly present their opinions on each model and help readers unfamiliar with
past modelling attempts understand the history of this area of research.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Deploying Zookeeper with Exhibitor to AWS using Ansible</title>
      <link>https://sookocheff.com/post/ansible/zookeeper-exhibitor-ansible/</link>
      <pubDate>Fri, 15 Jan 2016 09:46:48 +0000</pubDate>
      <guid>https://sookocheff.com/post/ansible/zookeeper-exhibitor-ansible/</guid>
      <description>&lt;p&gt;This article provides a detailed guide of deploying Zookeeper to AWS using
Exhibitor for cluster management. Exhibitor is a great help for managing your
cluster but getting things up and running is not well documented. Hopefully this
article corrects that deficiency.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Getting to Know Cloud Dataflow</title>
      <link>https://sookocheff.com/post/dataflow/get-to-know-dataflow/</link>
      <pubDate>Mon, 04 Jan 2016 09:12:37 -0600</pubDate>
      <guid>https://sookocheff.com/post/dataflow/get-to-know-dataflow/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://cloud.google.com/dataflow/&#34;&gt;Cloud Dataflow&lt;/a&gt; is Google&amp;rsquo;s managed service for batch and stream data processing. Dataflow provides a programming model and execution framework that allows you to run the same code in batch or streaming mode, with guarantees on correctness and primitives for correcting timing issues. Why should you care about Dataflow? A few reasons. First, Dataflow is the only stream processing framework that has strong consistency guarantees for &lt;a href=&#34;http://radar.oreilly.com/2015/11/building-systems-for-massive-scale-data-applications.html&#34;&gt;time series data&lt;/a&gt;. Second, Dataflow integrates well with the Google Cloud Platform and provides seamless methods for reading from and writing to the Datastore, PubSub, BigQuery and Cloud Storage. Third, the Dataflow SDK is open source and has received contributions for interfacing with Hadoop, Firebase, and Salesforce — AWS integration is absolutely possible. Lastly, Dataflow is completely managed, whereas competing offerings such as Spark and Flink typically run on top of a Hadoop installation used for intermediate storage.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Docker Step By Step: Containerizing Zookeeper</title>
      <link>https://sookocheff.com/post/docker/containerizing-zookeeper-a-guided-tour/</link>
      <pubDate>Fri, 04 Dec 2015 10:48:21 -0600</pubDate>
      <guid>https://sookocheff.com/post/docker/containerizing-zookeeper-a-guided-tour/</guid>
      <description>&lt;p&gt;Follow along with this article as we take a guided tour of containerizing
Zookeeper using Docker. This guide will show how to install Zookeeper to the
container, how to configure the Zookeeper application, and how to share data
volumes between the host and container.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why Java? Tales from a Python Convert</title>
      <link>https://sookocheff.com/post/java/why-java/</link>
      <pubDate>Fri, 20 Nov 2015 12:01:52 -0600</pubDate>
      <guid>https://sookocheff.com/post/java/why-java/</guid>
      <description>&lt;p&gt;Whenever I tell people I&amp;rsquo;ve been working with Java I get the same reaction:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Yuck! Java? Why Java?&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And, admittedly, I had the same reaction — at first. But over time, I&amp;rsquo;ve come to
appreciate Java for its type safety, performance, and rock-solid tooling. I&amp;rsquo;ve
also come to notice that this isn&amp;rsquo;t the Java I was used to — it&amp;rsquo;s been steadily
improving over the last ten years.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Including a local package as a Maven dependency</title>
      <link>https://sookocheff.com/post/java/local-maven-repository/</link>
      <pubDate>Thu, 12 Nov 2015 13:57:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/java/local-maven-repository/</guid>
      <description>&lt;p&gt;Lately I&amp;rsquo;ve been tasked with developing a Java library for internal use. For
testing, its proved useful to package the library for local use. This article
describes how to add a Jar file to a local Maven repository for use in your own
testing and development.&lt;/p&gt;
&lt;h2 id=&#34;create-your-local-maven-repository&#34;&gt;Create your local Maven repository&lt;/h2&gt;
&lt;p&gt;Your local Maven repository lives within the project you are developing for.
Creating your local repository is as simple as making a new directory.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Configuring an Upstream Remote</title>
      <link>https://sookocheff.com/post/git/configuring-an-upstream-remote/</link>
      <pubDate>Sun, 01 Nov 2015 21:10:21 -0600</pubDate>
      <guid>https://sookocheff.com/post/git/configuring-an-upstream-remote/</guid>
      <description>&lt;p&gt;This is something I often do but rarely remember the steps for. This post is
intended to serve as a reminder for me and anyone else having the same question:
how to add an upstream remote git repository.&lt;/p&gt;
&lt;p&gt;Start by forking the repository you are contributing to and cloning that
repository to your local file system. In this example, we will use the
Elasticsearch repository and assume you have cloned it locally.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Writing Repeated BigQuery records using the Java Client Library</title>
      <link>https://sookocheff.com/post/bigquery/writing-repeated-bigquery-records/</link>
      <pubDate>Tue, 27 Oct 2015 06:05:37 -0600</pubDate>
      <guid>https://sookocheff.com/post/bigquery/writing-repeated-bigquery-records/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve recently been working with Java via the Google Cloud Dataflow SDK. One
problem I&amp;rsquo;ve had is working with the BigQuery Java Client. It was never entirely
clear how to create a repeated record. This article explains how it works and
how you can accomplish the same thing.&lt;/p&gt;
&lt;p&gt;First, you need to create a new &lt;code&gt;TableRow&lt;/code&gt;. For this example, let&amp;rsquo;s assume we
are logging events using a guid and a timestamp.&lt;/p&gt;</description>
    </item>
    <item>
      <title>From JSON to a Google API Client Library object</title>
      <link>https://sookocheff.com/post/java/from-json-to-google-api-client-object/</link>
      <pubDate>Sun, 25 Oct 2015 06:57:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/java/from-json-to-google-api-client-object/</guid>
      <description>&lt;p&gt;I have been working on a Cloud Dataflow project that parses incoming App Engine logs to generate status statistics such as numer of errors in the last 10 minutes. The incoming data is a JSON representation of a &lt;a href=&#34;https://cloud.google.com/logging/docs/api/ref/rest/v1beta3/projects.logs.entries/write#LogEntry&#34;&gt;LogEntry&lt;/a&gt; object. A LogEntry object is represented in Java as a &lt;a href=&#34;https://developers.google.com/resources/api-libraries/documentation/logging/v1beta3/java/latest/com/google/api/services/logging/model/LogEntry.html&#34;&gt;LogEntry class&lt;/a&gt;. The task I found myself in was converting the JSON representation of a LogEntry into the Java object for downstream processing.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Maven runner for vim-test</title>
      <link>https://sookocheff.com/post/vim/maven-runner-for-vim-test/</link>
      <pubDate>Fri, 16 Oct 2015 09:22:09 -0600</pubDate>
      <guid>https://sookocheff.com/post/vim/maven-runner-for-vim-test/</guid>
      <description>&lt;p&gt;If you haven&amp;rsquo;t tried &lt;a href=&#34;https://github.com/janko-m/vim-test&#34;&gt;vim-test&lt;/a&gt; yet, please do. It provides a consistent interface for running unit tests from within vim for a variety of languages and test runners. It also has support for different methods of dispatching your tests from vim to a terminal to retrieve the results.&lt;/p&gt;
&lt;p&gt;vim-test works out of the box for a number of languages and is easily extensible
to support additional languages. In fact, I recently contributed a Maven test
runner for the Java language. If you are developing a Maven project, you can now
run your tests from within vim using vim-test.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Deploying Kafka to Google Compute Engine</title>
      <link>https://sookocheff.com/post/kafka/deploying-kafka-to-gce/</link>
      <pubDate>Mon, 12 Oct 2015 06:15:13 -0600</pubDate>
      <guid>https://sookocheff.com/post/kafka/deploying-kafka-to-gce/</guid>
      <description>&lt;p&gt;This article provides a startup script for deploying Kafka to a Google Compute Engine instance. This isn&amp;rsquo;t meant to be a production-ready system — it uses the &lt;a href=&#34;https://zookeeper.apache.org/&#34;&gt;Zookeeper&lt;/a&gt; instance embedded with Kafka and keeps most of the default settings. Instead, treat this as a quick and easy way do Kafka development using a live server.&lt;/p&gt;
&lt;p&gt;This article uses Compute Engine &lt;a href=&#34;https://cloud.google.com/compute/docs/startupscript?hl=en&#34;&gt;startup scripts&lt;/a&gt; to install and run Kafka on instance startup. Startup scripts allow you to run arbitrary Bash commands whenever an instance is created or restarted. Since this script is run on every restart, we lead with a check that makes sure we have not already ran the startup script and, if we have, we simply exit.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kafka Quick Start Guide</title>
      <link>https://sookocheff.com/post/kafka/kafka-quick-start/</link>
      <pubDate>Wed, 30 Sep 2015 06:30:42 -0600</pubDate>
      <guid>https://sookocheff.com/post/kafka/kafka-quick-start/</guid>
      <description>&lt;p&gt;If you’ve read the previous article describing &lt;a href=&#34;http://sookocheff.com/post/kafka/kafka-in-a-nutshell/&#34;&gt;Kafka in a Nutshell&lt;/a&gt; you may be itching to write an application using Kafka as a data backend. This article will get you part of the way there by describing how to deploy Kafka locally using &lt;a href=&#34;https://www.docker.com/&#34;&gt;Docker&lt;/a&gt; and test it using &lt;a href=&#34;https://github.com/edenhill/kafkacat&#34;&gt;kafkacat&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;running-kafka-locally&#34;&gt;Running Kafka Locally&lt;/h2&gt;
&lt;p&gt;First, if you haven&amp;rsquo;t already, download and install &lt;a href=&#34;http://docs.docker.com/mac/step_one/&#34;&gt;Docker&lt;/a&gt;. Once you have Docker installed, create a default virtual machine that will host your local Docker containers.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kafka in a Nutshell</title>
      <link>https://sookocheff.com/post/kafka/kafka-in-a-nutshell/</link>
      <pubDate>Fri, 25 Sep 2015 06:20:42 -0600</pubDate>
      <guid>https://sookocheff.com/post/kafka/kafka-in-a-nutshell/</guid>
      <description>&lt;p&gt;Kafka is a messaging system. That&amp;rsquo;s it. So why all the hype? In reality
messaging is a hugely important piece of infrastructure for moving data between
systems. To see why, let&amp;rsquo;s look at a data pipeline without a messaging system.&lt;/p&gt;
&lt;p&gt;This system starts with Hadoop for storage and data processing. Hadoop isn&amp;rsquo;t
very useful without data so the first stage in using Hadoop is getting data in.&lt;/p&gt;
&lt;figure&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;data-in.png&#34;/&gt; &lt;figcaption&gt;
            Bringing Data in to Hadoop
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;So far, not a big deal. Unfortunately, in the real world data exists on many
systems in parallel, all of which need to interact with Hadoop and with each
other. The situation quickly becomes more complex, ending with a system where
multiple data systems are talking to one another over many channels. Each of
these channels requires their own custom protocols and communication methods and
moving data between these systems becomes a full-time job for a team of
developers.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Beginning Docker</title>
      <link>https://sookocheff.com/post/docker/beginning-docker/</link>
      <pubDate>Mon, 14 Sep 2015 20:26:21 -0600</pubDate>
      <guid>https://sookocheff.com/post/docker/beginning-docker/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m writing this article as a means of tracking commonly used docker commands in
a place where I won&amp;rsquo;t forget them. If you find it useful or have additional
suggestions let me know in the comments.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Review of the Coursera Data Science Specialization</title>
      <link>https://sookocheff.com/post/datascience/datasciencespecialization/</link>
      <pubDate>Thu, 10 Sep 2015 06:29:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/datascience/datasciencespecialization/</guid>
      <description>&lt;h1 id=&#34;a-review-of-the-coursera-data-science-specialization&#34;&gt;A Review of the Coursera Data Science Specialization&lt;/h1&gt;
&lt;p&gt;I recently completed the 10th and final course in the Data Science Specialization offered by Coursera in conjunction with Johns Hopkins University. My background is as a computer scientist and programmer looking to learn more about statistical analysis and machine learning — I have always had an interest in data analysis and machine learning but never actually studied it. I used the Data Science Specialization acted as a starting point to learn more about the field and become familiar with typical problems and solutions that data scientists encounter in the field. This article describes my experience with the specialization and answers the question of whether or not the it is worth the time.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Counting N-Grams with Cloud Dataflow</title>
      <link>https://sookocheff.com/post/nlp/counting-n-grams-with-cloud-dataflow/</link>
      <pubDate>Wed, 05 Aug 2015 05:41:06 +0000</pubDate>
      <guid>https://sookocheff.com/post/nlp/counting-n-grams-with-cloud-dataflow/</guid>
      <description>&lt;p&gt;Counting &lt;a href=&#34;https://sookocheff.com/post/nlp/n-gram-modeling/&#34;&gt;n-grams&lt;/a&gt; is
a common pre-processing step for computing sentence and word probabilities
over a corpus. Thankfully, this task is &lt;a href=&#34;https://en.wikipedia.org/wiki/Embarrassingly_parallel&#34;&gt;embarrassingly
parallel&lt;/a&gt; and is
a natural fit for distributed processing frameworks like &lt;a href=&#34;https://cloud.google.com/dataflow/&#34;&gt;Cloud
Dataflow&lt;/a&gt;. This article provides an
implementation of n-gram counting using Cloud Dataflow that is able to
efficiently compute n-grams in parallel over massive datasets.&lt;/p&gt;
&lt;h2 id=&#34;the-algorithm&#34;&gt;The Algorithm&lt;/h2&gt;
&lt;p&gt;Cloud Dataflow uses a programming abstraction called &lt;code&gt;PCollections&lt;/code&gt; which are
collections of data that can be operated on in parallel (Parallel Collections).
When programming for Cloud Dataflow you treat each operation as a transformation
of a parallel collection that returns another parallel collection for further
processing. This style of development is similar to the traditional Unix
philosophy of piping the output of one command to another for further
processing.&lt;/p&gt;</description>
    </item>
    <item>
      <title>N-gram Modeling With Markov Chains</title>
      <link>https://sookocheff.com/post/nlp/ngram-modeling-with-markov-chains/</link>
      <pubDate>Fri, 31 Jul 2015 06:23:43 -0600</pubDate>
      <guid>https://sookocheff.com/post/nlp/ngram-modeling-with-markov-chains/</guid>
      <description>&lt;p&gt;A common method of reducing the complexity of n-gram modeling is using the
&lt;a href=&#34;https://en.wikipedia.org/wiki/Markov_property&#34;&gt;Markov Property&lt;/a&gt;. The Markov
Property states that the probability of future states depends only on the
present state, not on the sequence of events that preceded it. This concept can
be elegantly implemented using a &lt;a href=&#34;https://en.wikipedia.org/wiki/Markov_chain&#34;&gt;Markov
Chain&lt;/a&gt; storing the probabilities of
transitioning to a next state.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Modeling Natural Language with N-Gram Models</title>
      <link>https://sookocheff.com/post/nlp/n-gram-modeling/</link>
      <pubDate>Sat, 25 Jul 2015 06:41:06 +0000</pubDate>
      <guid>https://sookocheff.com/post/nlp/n-gram-modeling/</guid>
      <description>&lt;p&gt;One of the most widely used methods natural language is n-gram modeling. This
article explains what an n-gram model is, how it is computed, and what the
probabilities of an n-gram model tell us.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Structuring an Application using Model View Controller</title>
      <link>https://sookocheff.com/post/architecture/structuring-with-mvc/</link>
      <pubDate>Thu, 09 Jul 2015 19:40:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/architecture/structuring-with-mvc/</guid>
      <description>&lt;p&gt;Early pioneers in object-oriented programming paved the path towards using Model
View Controller (MVC) for graphical user interfaces as early as 1970 and web
applications have continued using the pattern to separate business logic from
display. This article attempts to clarify the use of Model View Controller
within web applications — giving consideration to the fact that most developers
will be building their application using an existing web framework.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Managed VMs and the Future of App Engine</title>
      <link>https://sookocheff.com/post/appengine/managed-vms/managed-vms-and-the-future-of-appengine/</link>
      <pubDate>Tue, 23 Jun 2015 20:33:37 -0600</pubDate>
      <guid>https://sookocheff.com/post/appengine/managed-vms/managed-vms-and-the-future-of-appengine/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been thinking about the transition of App Engine to Python 3 and have come
to the conclusion that it will never happen — App Engine will eventually be
deprecated in favour of Managed VMs. Let&amp;rsquo;s break this apart to see why this is.&lt;/p&gt;
&lt;p&gt;First, consider the effort required by Google to develop App Engine. The Python
runtime environment was modified to enforce the sandbox of the App
Engine environment. To provide a Python 3 environment for App Engine as we know
it, the Python 3 runtime would need to be modified with the same restrictions.
Even imagining that this would happen for Python 3.4, the effort to upgrade to
Python 3.5 would require additional effort by Google to modify the runtime.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Introducing CloudPyPI</title>
      <link>https://sookocheff.com/post/python/introducing-cloudpypi/</link>
      <pubDate>Tue, 16 Jun 2015 21:19:26 -0600</pubDate>
      <guid>https://sookocheff.com/post/python/introducing-cloudpypi/</guid>
      <description>&lt;p&gt;A common problem with Python development for large-scale teams is sharing
internal libraries. At Vendasta we&amp;rsquo;ve been solving this problem using a private
PyPI installation running on Google App Engine with Python eggs and wheels being
served by Google Cloud Storage. Today, we are announcing the open source version
of this tool — CloudPyPI.&lt;/p&gt;
&lt;p&gt;CloudPyPI is a modification of
&lt;a href=&#34;https://pypi.python.org/pypi/pypiserver&#34;&gt;pypiserver&lt;/a&gt; for running on Google App
Engine. We&amp;rsquo;ve also introduced a simple user management system to allow
authenticated access to your Python packages. Together, we&amp;rsquo;ve found this to be a
robust tool for distributing private Python libraries internally. If this is a
problem you&amp;rsquo;ve been trying to solve, give CloudPyPI a try — contributions and
feature requests are always welcome.&lt;/p&gt;</description>
    </item>
    <item>
      <title>App Engine Pipelines API - Part 6: The Pipeline UI</title>
      <link>https://sookocheff.com/post/appengine/pipelines/pipeline-ui/</link>
      <pubDate>Tue, 09 Jun 2015 20:43:56 -0600</pubDate>
      <guid>https://sookocheff.com/post/appengine/pipelines/pipeline-ui/</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://sookocheff.com/series/pipelines-api/&#34;&gt;View all articles in the Pipeline API Series&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This article will serve as a reminder of the Pipeline UI as much for the writer
as for the reader. The Pipeline UI requires the MapMeduce library to be
installed. If you are not familiar with MapReduce please refer to the &lt;a href=&#34;http://sookocheff.com/series/mapreduce-api/&#34;&gt;MapReduce
API Series of articles&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Once MapReduce is installed you will need to add a few indices to &lt;code&gt;index.yaml&lt;/code&gt;
to properly query for pipeline records for display in the UI.&lt;/p&gt;</description>
    </item>
    <item>
      <title>App Engine Pipelines API - Part 5: Asynchronous Pipelines</title>
      <link>https://sookocheff.com/post/appengine/pipelines/asynchronous-pipelines/</link>
      <pubDate>Tue, 02 Jun 2015 04:45:56 -0600</pubDate>
      <guid>https://sookocheff.com/post/appengine/pipelines/asynchronous-pipelines/</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://sookocheff.com/series/pipelines-api/&#34;&gt;View all articles in the Pipeline API Series&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This article will cover fully asynchronous pipelines. The term &amp;lsquo;asynchronous&amp;rsquo; is
misleading here — all piplines are asynchronous in the sense that yielding a
pipeline is a non-blocking operation. An asynchronous refers to a
pipeline that remains in a RUN state until outside action is taken, for example,
a button is clicked or a task is executed.&lt;/p&gt;
&lt;p&gt;Marking a pipeline as an asynchronous pipeline is as simple as setting the
&lt;code&gt;async&lt;/code&gt; class property to True.&lt;/p&gt;</description>
    </item>
    <item>
      <title>App Engine Pipelines API - Part 4: Pipeline Internals</title>
      <link>https://sookocheff.com/post/appengine/pipelines/pipeline-internals/</link>
      <pubDate>Wed, 27 May 2015 05:57:19 -0600</pubDate>
      <guid>https://sookocheff.com/post/appengine/pipelines/pipeline-internals/</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://sookocheff.com/series/pipelines-api/&#34;&gt;View all articles in the Pipeline API Series&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&#34;https://sookocheff.com/post/appengine/pipelines/connecting-pipelines/&#34;&gt;We&amp;rsquo;ve learned how to execute and chain together pipelines&lt;/a&gt;, now let&amp;rsquo;s
take a look at how pipelines execute under the hood. If necessary, you can
refer to the &lt;a href=&#34;https://github.com/GoogleCloudPlatform/appengine-pipelines&#34;&gt;source code of the pipelines
project&lt;/a&gt; to
clarify any details.&lt;/p&gt;
&lt;h2 id=&#34;the-pipeline-data-model&#34;&gt;The Pipeline Data Model&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s start with the pipeline data model. Note that each Kind defined by the
pipelines API is prefixed by &lt;code&gt;_AE_Pipeline&lt;/code&gt;, making it easy to view individual
pipeline details by viewing the datastore entity.&lt;/p&gt;</description>
    </item>
    <item>
      <title>App Engine Pipelines API - Part 3: Fan In, Fan Out, Sequencing</title>
      <link>https://sookocheff.com/post/appengine/pipelines/fan-in-fan-out/</link>
      <pubDate>Tue, 19 May 2015 05:57:19 -0600</pubDate>
      <guid>https://sookocheff.com/post/appengine/pipelines/fan-in-fan-out/</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://sookocheff.com/series/pipelines-api/&#34;&gt;View all articles in the Pipeline API Series&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&#34;https://sookocheff.com/post/appengine/pipelines/connecting-pipelines/&#34;&gt;Last time&lt;/a&gt;, we studied how to connect two pipelines together. In this post, we
expand on this topic, exploring how to fan-out to do multiple tasks in
parallel, fan-in to combine multiple tasks into one, and how to do
sequential work.&lt;/p&gt;</description>
    </item>
    <item>
      <title>App Engine Pipelines API - Part 2: Connecting Pipelines</title>
      <link>https://sookocheff.com/post/appengine/pipelines/connecting-pipelines/</link>
      <pubDate>Tue, 12 May 2015 05:57:19 -0600</pubDate>
      <guid>https://sookocheff.com/post/appengine/pipelines/connecting-pipelines/</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://sookocheff.com/series/pipelines-api/&#34;&gt;View all articles in the Pipeline API Series&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&#34;https://sookocheff.com/post/appengine/pipelines/the-basics/&#34;&gt;Last time&lt;/a&gt;, we discussed basic pipeline instantiation and execution. This time,
we will cover sequential pipelines, answering the question &amp;ldquo;How do
I connect the output of one pipeline with the input of another pipeline&amp;rdquo;?&lt;/p&gt;</description>
    </item>
    <item>
      <title>App Engine Pipelines API - Part 1: The Basics</title>
      <link>https://sookocheff.com/post/appengine/pipelines/the-basics/</link>
      <pubDate>Tue, 05 May 2015 05:57:19 -0600</pubDate>
      <guid>https://sookocheff.com/post/appengine/pipelines/the-basics/</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://sookocheff.com/series/pipelines-api/&#34;&gt;View all articles in the Pipeline API Series&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/GoogleCloudPlatform/appengine-pipelines&#34;&gt;Pipelines API&lt;/a&gt;
is a general purpose workflow engine for App Engine applications. With the
Pipelines API we can connect together complex workflows into a coherent run time
backed by the Datastore. This article provides a basic overview of the Pipelines
API and how it can be used for abritrary computational workflows.&lt;/p&gt;
&lt;p&gt;In the most basic sense a Pipeline is an object that takes input, performs some
logic or computation on that input, and produces output. Pipelines can take two
general forms &amp;ndash; synchronous or asynchronous. Synchronous pipelines act as basic
functions that must complete during a single request. Asynchronous pipelines
spawn child pipelines and connect them together into a workflow by passing input
and output parameters around.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Durabledict for App Engine</title>
      <link>https://sookocheff.com/post/appengine/durabledict-for-app-engine/</link>
      <pubDate>Wed, 29 Apr 2015 06:19:23 -0600</pubDate>
      <guid>https://sookocheff.com/post/appengine/durabledict-for-app-engine/</guid>
      <description>&lt;h2 id=&#34;tldr&#34;&gt;tldr;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/soofaloofa/datastoredict&#34;&gt;DatastoreDict&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;whats-a-durabledict&#34;&gt;What&amp;rsquo;s a durabledict?&lt;/h2&gt;
&lt;p&gt;Good question. &lt;a href=&#34;https://github.com/disqus/durabledict&#34;&gt;Durabledict&lt;/a&gt; is a Python
implementation of a persistent dictionary. The dictionary values are cached
locally and sync with the datastore whenever a value in the datastore changes.&lt;/p&gt;
&lt;p&gt;Disqus provides concrete implementations for Redis, Django, ZooKeeper and in
memory. This blog post details an implementation using the App Engine datastore
and memcache.&lt;/p&gt;
&lt;h2 id=&#34;creating-your-own-durabledict&#34;&gt;Creating your own durabledict&lt;/h2&gt;
&lt;p&gt;By following the &lt;a href=&#34;https://github.com/disqus/durabledict&#34;&gt;guide the durabledict
README&lt;/a&gt; we can create our own
implementation. We need to subclass &lt;code&gt;durabledict.base.DurableDict&lt;/code&gt; and implement
the following interface methods. Strictly speaking, &lt;code&gt;_pop&lt;/code&gt; and &lt;code&gt;_setdefault&lt;/code&gt; do
not have to be implemented but doing so makes your durabledict behave like a
base dict in all cases.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Continuous Delivery Distilled</title>
      <link>https://sookocheff.com/post/continuous-delivery/continuous-delivery-distilled/</link>
      <pubDate>Thu, 23 Apr 2015 08:32:37 -0600</pubDate>
      <guid>https://sookocheff.com/post/continuous-delivery/continuous-delivery-distilled/</guid>
      <description>&lt;iframe width=&#34;560&#34; height=&#34;315&#34; src=&#34;https://www.youtube.com/embed/-B0ZEHmBCH8&#34; frameborder=&#34;0&#34; allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;What if you could deliver more value, with more speed and with more stability?&lt;/p&gt;
&lt;p&gt;What if you could triage bugs faster?&lt;/p&gt;
&lt;p&gt;What if you could fix bugs easier and with less user facing impact?&lt;/p&gt;
&lt;p&gt;You can, with continuous delivery.&lt;/p&gt;
&lt;h2 id=&#34;terminology&#34;&gt;Terminology&lt;/h2&gt;
&lt;p&gt;First, some terminology. What distinguishes continuous integration, continuous
deployment and continuous delivery? Continuous integration revolves around the
continuous automated testing of software whenever change to the software is
made. Continuous deployment is the practice of automatically deploying any
change to the code. Continuous delivery implies that you can deploy any change
to production but for any number of reasons you may choose not to. The focus of
this article is on continuous delivery.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Creating a BigQuery Table using the Java Client Library</title>
      <link>https://sookocheff.com/post/bigquery/creating-a-big-query-table-java-api/</link>
      <pubDate>Mon, 23 Mar 2015 15:32:37 -0600</pubDate>
      <guid>https://sookocheff.com/post/bigquery/creating-a-big-query-table-java-api/</guid>
      <description>&lt;p&gt;I haven&amp;rsquo;t been able to find great documentation on creating a BigQuery
TableSchema using the Java Client Library. This blog post hopes to rectify that
:).&lt;/p&gt;
&lt;p&gt;You can use the &lt;a href=&#34;https://github.com/GoogleCloudPlatform/bigquery-samples-java&#34;&gt;BigQuery sample
code&lt;/a&gt; for an idea
of how to create a client connection to BigQuery. Assuming you have the
connection set up you can start by creating a new &lt;code&gt;TableSchema&lt;/code&gt;. The
&lt;code&gt;TableSchema&lt;/code&gt; provides a method for setting the list of fields that make up the
columns of your BigQuery Table. Those columns are defined as an Array of
&lt;code&gt;TableFieldSchema&lt;/code&gt; objects.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Deploying R Studio on Compute Engine</title>
      <link>https://sookocheff.com/post/r/deploying-r-studio-to-compute-engine/</link>
      <pubDate>Mon, 23 Mar 2015 15:32:37 -0600</pubDate>
      <guid>https://sookocheff.com/post/r/deploying-r-studio-to-compute-engine/</guid>
      <description>&lt;p&gt;Sometimes you have a data analysis problem that is just too big for your desktop
or laptop. The limiting factor here is generally RAM. Thankfully, services like
Google Compute Engine allow you to lease servers with up to 208GB of RAM, large
enough for a wide variety of intensive tasks. An ancillary benefit of using a
service like Compute Engine is that it allows you to easily load your data from
a Cloud Storage Bucket, meaning you don&amp;rsquo;t need to keep a copy of the large
dataset locally at all times.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Keeping App Engine Search Documents and Datastore Entities In Sync</title>
      <link>https://sookocheff.com/post/appengine/syncing-search-documents-with-datastore-entities/</link>
      <pubDate>Mon, 23 Feb 2015 08:20:37 -0600</pubDate>
      <guid>https://sookocheff.com/post/appengine/syncing-search-documents-with-datastore-entities/</guid>
      <description>&lt;p&gt;At Vendasta the App Engine Datastore serves as the single point of truth for
most operational data and the majority of interactions are against this single
point of truth. However, a piece of required functionality in many of our
products is to provide a searchable view of the data in the App Engine
Datastore. Search is difficult using the Datastore and so we have moved to using
the &lt;a href=&#34;https://cloud.google.com/appengine/docs/python/search/&#34;&gt;Search API&lt;/a&gt; as a
managed solution for searching datastore entities. In this use case, every edit
to an entity in the Datastore is reflected as a change to a Search Document.
This article details an architecture for keeping Datastore entities and Search
Documents in sync throughout failure and race conditions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Halting Python unittest Execution on First Error</title>
      <link>https://sookocheff.com/post/python/halting-unittest-execution-at-first-error/</link>
      <pubDate>Thu, 12 Feb 2015 06:20:37 -0600</pubDate>
      <guid>https://sookocheff.com/post/python/halting-unittest-execution-at-first-error/</guid>
      <description>&lt;p&gt;We all know the importance of unit tests. Especially in a dynamic language like
Python. Occasionally you have a set of unit tests that are failing in a
cascading fashion where the first error case causes subsequent tests to fail
(these tests are likely no longer unit tests, but that&amp;rsquo;s a different
discussion). To help isolate the offending test case in a see of failures you
can set the &lt;code&gt;unittest.TestCase&lt;/code&gt; class to halt after the first error by
overriding the &lt;code&gt;run&lt;/code&gt; method as follows.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Create a Google Cloud Dataflow Project with Gradle</title>
      <link>https://sookocheff.com/post/dataflow/cloud-dataflow-with-gradle/</link>
      <pubDate>Wed, 11 Feb 2015 06:20:37 -0600</pubDate>
      <guid>https://sookocheff.com/post/dataflow/cloud-dataflow-with-gradle/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been experimenting with the &lt;a href=&#34;https://cloud.google.com/dataflow/&#34;&gt;Google Cloud
Dataflow&lt;/a&gt; &lt;a href=&#34;https://github.com/GoogleCloudPlatform/DataflowJavaSDK&#34;&gt;Java
SDK&lt;/a&gt; for running managed
data processing pipelines. One of the first tasks is getting a build environment
up and running. For this I chose Gradle.&lt;/p&gt;
&lt;p&gt;We start by declaring this a java application and listing the configuration
variables that declare the source compatibility level (which for now must be
1.7) and the main class to be executed by the &lt;code&gt;run&lt;/code&gt; task to be defined later.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A pypiserver Deployment Script</title>
      <link>https://sookocheff.com/post/python/a-pypiserver-deployment-script/</link>
      <pubDate>Sun, 01 Feb 2015 14:53:37 -0600</pubDate>
      <guid>https://sookocheff.com/post/python/a-pypiserver-deployment-script/</guid>
      <description>&lt;p&gt;At Vendasta we&amp;rsquo;ve been slowly adopting pypi and pip for our internal code
libraries and the time has come to deploy our own private pypi server. After
evaluating a few options I settled on the simplistic
&lt;a href=&#34;https://pypi.python.org/pypi/pypiserver&#34;&gt;pypiserver&lt;/a&gt; &amp;ndash; a barebones
implementation of the &lt;a href=&#34;https://pypi.python.org/simple/&#34;&gt;simple HTTP API&lt;/a&gt; to
pypi.&lt;/p&gt;
&lt;p&gt;The deployment uses nginx as a front-end to pypiserver. pypiserver itself is ran
and monitored using supervisord. I created a bash script that creates a user and
group to run pypiserver and installs and runs nginx, supervisord and pypiserver.
I&amp;rsquo;ve been running this bash script through Vagrant to deploy a custom pypiserver
for private use. I wanted to save this code for posterity and hopefully help
someone else working on the same task.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Downloading files from Google Cloud Storage with webapp2</title>
      <link>https://sookocheff.com/post/appengine/webapp2-download-handler/</link>
      <pubDate>Tue, 27 Jan 2015 06:07:12 -0600</pubDate>
      <guid>https://sookocheff.com/post/appengine/webapp2-download-handler/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been working on a simple App Engine application that offers upload and
download functionality to and from Google Cloud Storage. When it came time to
actually download the content I needed to write a webapp2 &lt;code&gt;RequestHandler&lt;/code&gt; that
will retrieve the file from Cloud Storage and return it to the client.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Querying App Engine Logs with Elasticsearch</title>
      <link>https://sookocheff.com/post/appengine/querying-app-engine-logs-with-elasticsearch/</link>
      <pubDate>Fri, 23 Jan 2015 06:15:07 +0000</pubDate>
      <guid>https://sookocheff.com/post/appengine/querying-app-engine-logs-with-elasticsearch/</guid>
      <description>&lt;p&gt;From a DevOps perspective having a historical record of application logs can aid
immensely in tracking down bugs, responding to customer questions, or finding
out when and why that critical piece of data was updated to the wrong value. One
of the biggest grievances with the built-in log handling of Google App Engine is
that historical logs are only available for the previous three days. We wanted
to do a little bit better and have logs available for a 30 day time period. This
article outlines a method we&amp;rsquo;ve developed for pushing App Engine logs to an
elasticsearch cluster.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Parsing bash script options with getopts</title>
      <link>https://sookocheff.com/post/bash/parsing-bash-script-arguments-with-shopts/</link>
      <pubDate>Sun, 04 Jan 2015 12:31:51 +0000</pubDate>
      <guid>https://sookocheff.com/post/bash/parsing-bash-script-arguments-with-shopts/</guid>
      <description>&lt;p&gt;A common task in shell scripting is to parse command line arguments to your
script. Bash provides the &lt;code&gt;getopts&lt;/code&gt; built-in function to do just that. This
tutorial explains how to use the &lt;code&gt;getopts&lt;/code&gt; built-in function to parse arguments and options to a bash script.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Managing App Engine Dependencies Using pip</title>
      <link>https://sookocheff.com/post/appengine/managing-app-engine-dependencies-with-pip/</link>
      <pubDate>Tue, 30 Dec 2014 20:35:48 +0000</pubDate>
      <guid>https://sookocheff.com/post/appengine/managing-app-engine-dependencies-with-pip/</guid>
      <description>&lt;p&gt;One unfortunate difficulty when working with App Engine is managing your local
dependencies. You don&amp;rsquo;t have access to your Python environment so all libraries
you wish to use must be &lt;em&gt;vendored&lt;/em&gt; with your installation. That is, you need to
copy all of your library code into a local folder to ship along with your app.&lt;/p&gt;</description>
    </item>
    <item>
      <title>App Engine MapReduce API - Part 7: Writing a Custom Output Writer</title>
      <link>https://sookocheff.com/post/appengine/mapreduce/writing-a-custom-output-writer/</link>
      <pubDate>Mon, 22 Dec 2014 07:07:35 +0000</pubDate>
      <guid>https://sookocheff.com/post/appengine/mapreduce/writing-a-custom-output-writer/</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href=&#34;http://sookocheff.com/series/mapreduce-api/&#34;&gt;View all articles in the MapReduce API Series&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The MapReduce library supports a number of default output writers. You can also
write your own that implements the output writer interface. This article
examines how to write a custom output writer that pushes data from the App
Engine datastore to an elasticsearch cluster. A similar pattern can be followed
to push the output from your MapReduce job to any number of places.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Bash String Operators</title>
      <link>https://sookocheff.com/post/bash/bash-string-operators/</link>
      <pubDate>Thu, 11 Dec 2014 19:54:12 +0000</pubDate>
      <guid>https://sookocheff.com/post/bash/bash-string-operators/</guid>
      <description>&lt;p&gt;A common task in &lt;em&gt;bash&lt;/em&gt; programming is to manipulate portions of a string and
return the result. &lt;em&gt;bash&lt;/em&gt; provides rich support for these manipulations via
string operators. The syntax is not always intuitive so I wanted to use this
blog post to serve as a permanent reminder of the operators.&lt;/p&gt;
&lt;p&gt;The string operators are signified with the &lt;code&gt;${}&lt;/code&gt; notation. The operations can be
grouped in to a few classes. Each heading in this article describes a class of
operation.&lt;/p&gt;</description>
    </item>
    <item>
      <title>App Engine MapReduce API - Part 6: Writing a Custom Input Reader</title>
      <link>https://sookocheff.com/post/appengine/mapreduce/writing-a-custom-input-reader/</link>
      <pubDate>Thu, 04 Dec 2014 22:54:12 +0000</pubDate>
      <guid>https://sookocheff.com/post/appengine/mapreduce/writing-a-custom-input-reader/</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href=&#34;http://sookocheff.com/series/mapreduce-api/&#34;&gt;View all articles in the MapReduce API Series&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;One of the great things about the MapReduce library is the abilitiy to write a
cutom InputReader to process data from any data source. In this post we will
explore how to write an InputReader the leases tasks from an AppEngine pull
queue by implementing the &lt;code&gt;InputReader&lt;/code&gt; interface.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Installing MySQL-Python on OS X Yosemite</title>
      <link>https://sookocheff.com/post/tools/installing-mysql-python-on-yosemite/</link>
      <pubDate>Tue, 18 Nov 2014 11:15:23 +0000</pubDate>
      <guid>https://sookocheff.com/post/tools/installing-mysql-python-on-yosemite/</guid>
      <description>&lt;p&gt;Installing the MySQL-Python package requires a few steps. In an effort to aid
future Internet travellers, this post will document how to install the
MySQL-Python package on OS X Yosemite.&lt;/p&gt;
&lt;p&gt;First, install MariaDB, the drop-in replacement for MySQL. I chose MacPorts for
this task, though Homebrew would work just fine. Second, update your PATH to
include the mariadb executables. Third, install the Python MySQL connector.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo port install mariadb
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PATH&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/opt/local/lib/mariadb/bin:&lt;span class=&#34;nv&#34;&gt;$PATH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install MySQL-Python
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s it! You should be able to &lt;code&gt;import MySQLdb&lt;/code&gt; in your Python code and
interact with your MariaDB database.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Automatically Resizing a Compute Engine Disk</title>
      <link>https://sookocheff.com/post/compute-engine/automatically-resizing-a-compute-engine-disk/</link>
      <pubDate>Tue, 11 Nov 2014 19:21:45 +0000</pubDate>
      <guid>https://sookocheff.com/post/compute-engine/automatically-resizing-a-compute-engine-disk/</guid>
      <description>&lt;p&gt;A recurring issue when working with &lt;a href=&#34;https://cloud.google.com/compute/&#34;&gt;Compute
Engine&lt;/a&gt; is that newly created Instances have
only 10GB of free space available. To take advantage of the full disk size you
need to manually partition and resize it. This article shows one method of
accomplishing this task.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Guided Tour of Google Compute Engine</title>
      <link>https://sookocheff.com/post/compute-engine/a-guided-tour-of-compute-engine/</link>
      <pubDate>Wed, 05 Nov 2014 04:45:05 +0000</pubDate>
      <guid>https://sookocheff.com/post/compute-engine/a-guided-tour-of-compute-engine/</guid>
      <description>&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;The Google &lt;a href=&#34;https://www.youtube.com/watch?v=43gvHZyPRVk&#34;&gt;Compute Engine core
concepts video&lt;/a&gt; provides a great
overview of the technology. Please take a moment to watch it. As the video
shows, Compute Engine is defined by Resources, and each of these Resources is
available through the Compute Engine API. You can access this API through the
Google API Explorer or by installing the &lt;a href=&#34;https://cloud.google.com/sdk/&#34;&gt;gcloud sdk&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Extracting the Start Sector of a Disk with fdisk</title>
      <link>https://sookocheff.com/post/linux/extracting-the-start-sector-with-fdisk/</link>
      <pubDate>Mon, 03 Nov 2014 05:49:31 +0000</pubDate>
      <guid>https://sookocheff.com/post/linux/extracting-the-start-sector-with-fdisk/</guid>
      <description>&lt;p&gt;fdisk is a wonderful little utility for managing partitions. I recently had to
script a series of fdisk commands for resizing a partition and needed to extract
the start sector from the existing disk to do so. I ended up using this
combination of &lt;code&gt;grep&lt;/code&gt; and &lt;code&gt;awk&lt;/code&gt; to do the job.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Packaging a Compute Engine Virtual Machine Image</title>
      <link>https://sookocheff.com/post/compute-engine/packaging-a-compute-engine-vm/</link>
      <pubDate>Tue, 28 Oct 2014 06:03:42 +0000</pubDate>
      <guid>https://sookocheff.com/post/compute-engine/packaging-a-compute-engine-vm/</guid>
      <description>&lt;p&gt;Google Compute Engine allows you to make custom images from a running virtual
machine. The documentation provides a sufficient example but is a little bit
scattered. This article collects and presents all the steps necessary to create
your own Compute Engine images that you can use as a base for virtual machines.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Using the Google Prediction API to Predict the Sentiment of a Tweet</title>
      <link>https://sookocheff.com/post/prediction-api/predicting-sentiment/</link>
      <pubDate>Mon, 20 Oct 2014 06:23:04 +0000</pubDate>
      <guid>https://sookocheff.com/post/prediction-api/predicting-sentiment/</guid>
      <description>&lt;p&gt;The &lt;a href=&#34;https://cloud.google.com/prediction/&#34;&gt;Google Prediction API&lt;/a&gt; offers the
power of Google&amp;rsquo;s machine learning algorithms over a RESTful API interface. The
machine learning algorithms themselves are a complete black box. As a user you
upload the training data and, once it has been analyzed, start classifying new
observations based on the analysis of the training data. I recently spent some
time investigating how to use the API to determine the sentiment of a tweet.
This article collects my thoughts on the experience and a few recommendations
for future work.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Suggested Searches with Google App Engine</title>
      <link>https://sookocheff.com/post/appengine/suggested-searches/</link>
      <pubDate>Mon, 06 Oct 2014 05:52:29 +0000</pubDate>
      <guid>https://sookocheff.com/post/appengine/suggested-searches/</guid>
      <description>&lt;p&gt;At &lt;a href=&#34;http://www.vendasta.com&#34;&gt;VendAsta&lt;/a&gt; we have a few APIs that are backed by
search documents built using the &lt;a href=&#34;https://cloud.google.com/appengine/docs/python/search/&#34;&gt;App Engine Search
API&lt;/a&gt;. These APIs are
queried using a search string entered in a text box. One way to improve the user
experience of this text box is to offer the user suggestions of popular searches
to use as their query. This article describes how to achieve this.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Composing Asynchronous Functions With Tasklets</title>
      <link>https://sookocheff.com/post/appengine/ndb/composing-asynchronous-functions-with-tasklets/</link>
      <pubDate>Sat, 27 Sep 2014 15:25:29 +0000</pubDate>
      <guid>https://sookocheff.com/post/appengine/ndb/composing-asynchronous-functions-with-tasklets/</guid>
      <description>&lt;p&gt;Asynchronous functions can provide a boon to application performance by allowing time consuming functions to operate in parallel and without blocking the main execution thread. This article explains how to use the Tasklet API to compose and execute asynchronous functions in Google App Engine.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Working From Home: A Retrospective</title>
      <link>https://sookocheff.com/post/opinion/working-from-home-retrospective/</link>
      <pubDate>Thu, 18 Sep 2014 12:57:32 +0000</pubDate>
      <guid>https://sookocheff.com/post/opinion/working-from-home-retrospective/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve spent the past eight months working from home thanks to some great support
from my &lt;a href=&#34;http://www.vendasta.com&#34;&gt;employer&lt;/a&gt;, allowing me to support my wife and
children and still contribute as a meaningful employee. Working from home with
four small children and a loving and supportive wife has brought its fair share
of both challenges and delights. This post will describe the working from home
experience and the lessons I&amp;rsquo;ve learned along the way.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Converting an ndb model to a BigQuery schema</title>
      <link>https://sookocheff.com/post/appengine/ndb/converting-an-ndb-model-to-a-bigquery-schema/</link>
      <pubDate>Thu, 14 Aug 2014 17:58:03 +0000</pubDate>
      <guid>https://sookocheff.com/post/appengine/ndb/converting-an-ndb-model-to-a-bigquery-schema/</guid>
      <description>&lt;p&gt;I have been working on the problem of recording changes to an ndb model. One way to accomplish this is to stream data changes to a BigQuery table corresponding to the ndb model. It would be great to do this in a generic way which gives us the problem of generating a BigQuery table given an ndb model. This article will describe one solution to this problem.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Restoring an App Engine backup into a Big Query table</title>
      <link>https://sookocheff.com/post/appengine/restoring-an-app-engine-backup/</link>
      <pubDate>Mon, 04 Aug 2014 21:18:13 +0000</pubDate>
      <guid>https://sookocheff.com/post/appengine/restoring-an-app-engine-backup/</guid>
      <description>&lt;p&gt;An unfortunate DevOps task for any team running App Engine is restoring data
from backups. One way to do this is by accessing the Google Cloud Storage URL
for a given App Engine backup and importing that backup into BigQuery. This
article will show you to get the Cloud Storage URL for an App Engine backup and
manually perform that import.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Bypassing ndb hooks with the RawDatastoreInputReader</title>
      <link>https://sookocheff.com/post/appengine/ndb/bypassing-ndb-hooks-with-the-raw-datastore-input-reader/</link>
      <pubDate>Tue, 29 Jul 2014 20:32:42 +0000</pubDate>
      <guid>https://sookocheff.com/post/appengine/ndb/bypassing-ndb-hooks-with-the-raw-datastore-input-reader/</guid>
      <description>&lt;p&gt;When doing a MapReduce operation there are times when you want to edit a set of
entities without triggering the post or pre put hooks associated with those
entities. On such ocassions using the raw datastore entity allows you to process
the data without unwanted side effects. This article will show how to use the
RawDatastoreInputReader to process datastore entities.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Generating a C# client for an App Engine Cloud Endpoints API</title>
      <link>https://sookocheff.com/post/appengine/cloud-endpoints/generating-a-c-sharp-client/</link>
      <pubDate>Tue, 22 Jul 2014 06:29:56 +0000</pubDate>
      <guid>https://sookocheff.com/post/appengine/cloud-endpoints/generating-a-c-sharp-client/</guid>
      <description>&lt;p&gt;The Cloud Endpoints API comes packaged with endpointscfg.py to generate client
libraries in JavaScript, Objective-C (for iOS) and Java (for Android). You can
also generate a few additional client libraries using the &lt;a href=&#34;https://code.google.com/p/google-apis-client-generator/&#34;&gt;Google APIs client
generator&lt;/a&gt;. This
article will show you how to use the generator to create a C# client library.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Using Basic Authentication with Google Cloud Endpoints</title>
      <link>https://sookocheff.com/post/appengine/cloud-endpoints/using-basic-authentication-with-google-cloud-endpoints/</link>
      <pubDate>Wed, 16 Jul 2014 01:02:25 +0000</pubDate>
      <guid>https://sookocheff.com/post/appengine/cloud-endpoints/using-basic-authentication-with-google-cloud-endpoints/</guid>
      <description>&lt;p&gt;Cloud Endpoints provides strong integration with OAuth 2.0. If you can use this
integration &amp;ndash; do it. However, some legacy systems require supporting
alternative authentication mechanisms. This article will show you how to secure
an API endpoint using Basic Authentication. You can use this as a starting point
for whatever authentication method you choose.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Unit Testing Cloud Endpoints</title>
      <link>https://sookocheff.com/post/appengine/cloud-endpoints/unit-testing-cloud-endpoints/</link>
      <pubDate>Thu, 10 Jul 2014 14:32:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/appengine/cloud-endpoints/unit-testing-cloud-endpoints/</guid>
      <description>&lt;p&gt;Writing unit tests for App Engine Cloud Endpoints is a fairly straight forward
process. Unfortunately it is not well documented and a few gotchas exist. This
article provides a template you can use to unit test Cloud Endpoints including
full source code for a working example.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Creating RESTful APIs with App Engine Cloud Endpoints</title>
      <link>https://sookocheff.com/post/appengine/cloud-endpoints/creating-restful-apis-with-cloud-endpoints/</link>
      <pubDate>Wed, 02 Jul 2014 06:14:23 +0000</pubDate>
      <guid>https://sookocheff.com/post/appengine/cloud-endpoints/creating-restful-apis-with-cloud-endpoints/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://developers.google.com/appengine/docs/python/endpoints/&#34;&gt;App Engine Cloud
Endpoints&lt;/a&gt; is a
great way to quickly and easily create JSON API endpoints. What&amp;rsquo;s not clear is
how to structure your &lt;code&gt;Message&lt;/code&gt; code to support a RESTful
create-read-update-delete (CRUD) API. This article will show the basic CRUD
operations for one Resource. The results can easily be adapted to support a full
REST API.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Running Multiple App Engine Modules Locally with dev_appserver.py</title>
      <link>https://sookocheff.com/post/appengine/running-multiple-app-engine-modules-locally/</link>
      <pubDate>Tue, 17 Jun 2014 13:09:42 +0000</pubDate>
      <guid>https://sookocheff.com/post/appengine/running-multiple-app-engine-modules-locally/</guid>
      <description>&lt;p&gt;The recently released &lt;a href=&#34;https://developers.google.com/appengine/docs/python/modules/&#34;&gt;App Engine Modules API&lt;/a&gt; allows developers to compartmentalize their applications into logical units that can share state using the datastore or memcache.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Downloading directories of code from Github using the Github API</title>
      <link>https://sookocheff.com/post/tools/downloading-directories-of-code-from-github-using-the-github-api/</link>
      <pubDate>Tue, 17 Jun 2014 06:14:23 +0000</pubDate>
      <guid>https://sookocheff.com/post/tools/downloading-directories-of-code-from-github-using-the-github-api/</guid>
      <description>&lt;p&gt;At &lt;a href=&#34;http://www.vendAsta.com&#34;&gt;VendAsta&lt;/a&gt; we frequently share libraries of code
between projects. To make it easier to share this code I&amp;rsquo;ve developed a small
package manager that downloads code within a directory from Github to be copied
in to your current project. It&amp;rsquo;s a quick and dirty alternative to cloning an
entire repository, grabbing the set of files you want and placing them in your
project.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to bypass the auto_now property option during an ndb put</title>
      <link>https://sookocheff.com/post/appengine/ndb/how-to-bypass-the-auto-now-property-option-during-an-ndb-put/</link>
      <pubDate>Wed, 28 May 2014 05:55:48 +0000</pubDate>
      <guid>https://sookocheff.com/post/appengine/ndb/how-to-bypass-the-auto-now-property-option-during-an-ndb-put/</guid>
      <description>&lt;p&gt;In App Engine the &lt;code&gt;auto_now&lt;/code&gt; option sets a property to the current date/time
whenever the entity is created or updated. This is a great feature for tracking
the time when an entity was last updated. However, sometimes you may want to put
an entity without updating an &lt;code&gt;auto_now&lt;/code&gt; timestamp. This article will show you
how.&lt;/p&gt;</description>
    </item>
    <item>
      <title>App Engine MapReduce API - Part 5: Using Combiners to Reduce Data Throughput</title>
      <link>https://sookocheff.com/post/appengine/mapreduce/using-combiners-to-reduce-data-throughput/</link>
      <pubDate>Tue, 20 May 2014 08:54:12 +0000</pubDate>
      <guid>https://sookocheff.com/post/appengine/mapreduce/using-combiners-to-reduce-data-throughput/</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href=&#34;http://sookocheff.com/series/mapreduce-api/&#34;&gt;View all articles in the MapReduce API Series&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So far we&amp;rsquo;ve looked at using MapReduce pipelines to perform calculations over
large data sets and combined multiple pipelines in succession. In this article
we will look at how to reduce the amount of data transfer by using a combiner.&lt;/p&gt;</description>
    </item>
    <item>
      <title>App Engine MapReduce API - Part 4: Combining Sequential MapReduce Jobs</title>
      <link>https://sookocheff.com/post/appengine/mapreduce/combining-sequential-mapreduce-jobs/</link>
      <pubDate>Tue, 13 May 2014 10:40:38 +0000</pubDate>
      <guid>https://sookocheff.com/post/appengine/mapreduce/combining-sequential-mapreduce-jobs/</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href=&#34;http://sookocheff.com/series/mapreduce-api/&#34;&gt;View all articles in the MapReduce API Series&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Last time we looked at how to run a full MapReduce Pipeline to count the number of
occurrences of a character within each string. In this post we will see how to
chain multiple MapReduce Pipelines together to perform sequential tasks.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Installing lxml on OS X Mavericks</title>
      <link>https://sookocheff.com/post/python/installing-lxml-on-os-x-mavericks/</link>
      <pubDate>Wed, 07 May 2014 10:26:45 +0000</pubDate>
      <guid>https://sookocheff.com/post/python/installing-lxml-on-os-x-mavericks/</guid>
      <description>&lt;p&gt;I recently tried installing lxml for use within an App Engine project on OS X
Mavericks only to be hit with an error message from &lt;code&gt;clang&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>App Engine MapReduce API - Part 3: Programmatic MapReduce using Pipelines</title>
      <link>https://sookocheff.com/post/appengine/mapreduce/programmatic-mapreduce/</link>
      <pubDate>Mon, 28 Apr 2014 21:51:22 +0000</pubDate>
      <guid>https://sookocheff.com/post/appengine/mapreduce/programmatic-mapreduce/</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href=&#34;http://sookocheff.com/series/mapreduce-api/&#34;&gt;View all articles in the MapReduce API Series&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In the last article we examined how to run one-off tasks that operate on a large dataset using a &lt;code&gt;mapreduce.yaml&lt;/code&gt; configuration file. This article will take us a step further and look at how to run a MapReduce job programmatically using the App Engine Pipeline API.&lt;/p&gt;</description>
    </item>
    <item>
      <title>App Engine MapReduce API - Part 2: Running a MapReduce Job Using mapreduce.yaml</title>
      <link>https://sookocheff.com/post/appengine/mapreduce/mapreduce-yaml/</link>
      <pubDate>Tue, 22 Apr 2014 06:48:36 +0000</pubDate>
      <guid>https://sookocheff.com/post/appengine/mapreduce/mapreduce-yaml/</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href=&#34;http://sookocheff.com/series/mapreduce-api/&#34;&gt;View all articles in the MapReduce API Series&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Last time we looked at an overview of how MapReduce works. In this article we&amp;rsquo;ll be getting our hands dirty writing some code to handle the Map Stage. If you&amp;rsquo;ll recall, the Map Stage is composed of two separate components: an InputReader and a &lt;code&gt;map&lt;/code&gt; function. We&amp;rsquo;ll look at each of these in turn.&lt;/p&gt;</description>
    </item>
    <item>
      <title>App Engine MapReduce API - Part 1: The Basics</title>
      <link>https://sookocheff.com/post/appengine/mapreduce/the-basics/</link>
      <pubDate>Tue, 15 Apr 2014 12:09:36 +0000</pubDate>
      <guid>https://sookocheff.com/post/appengine/mapreduce/the-basics/</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href=&#34;http://sookocheff.com/series/mapreduce-api/&#34;&gt;View all articles in the MapReduce API Series&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The first arcticle in this series provides an overview of the &lt;a href=&#34;https://developers.google.com/appengine/docs/python/dataprocessing/&#34;&gt;App Engine MapReduce
API&lt;/a&gt;. We
will give a basic overview of what MapReduce is and how it is used to do
parallel and distributed processing of large datasets.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Understanding JSON Patch</title>
      <link>https://sookocheff.com/post/api/understanding-json-patch/</link>
      <pubDate>Tue, 08 Apr 2014 16:12:14 +0000</pubDate>
      <guid>https://sookocheff.com/post/api/understanding-json-patch/</guid>
      <description>&lt;p&gt;The typical update cycle for an API resource is to (1) GET the representation, (2) modify it and (3) PUT back the entire representation. This can waste bandwidth and processing time for large resources. An alternative is to use the &lt;a href=&#34;https://tools.ietf.org/html/rfc5789&#34;&gt;HTTP PATCH&lt;/a&gt; extension method to only send the differences between two resources. HTTP PATCH applies a set of changes to the document referenced by the HTTP request.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Version a REST API</title>
      <link>https://sookocheff.com/post/api/how-to-version-a-rest-api/</link>
      <pubDate>Tue, 01 Apr 2014 14:16:18 +0000</pubDate>
      <guid>https://sookocheff.com/post/api/how-to-version-a-rest-api/</guid>
      <description>&lt;p&gt;API versioning is a fact of life. Even the most well designed API changes as new features and relationships are uncovered. Unfortunately, updating an API is seldom as simple as changing the behaviour of our existing URL endpoints on her he server. If we have existing clients we need to explicitly advertise breaking changes in a seamless way. This article explains a few methods of specifying breaking changes that offer a clear upgrade path for existing API clients.&lt;/p&gt;</description>
    </item>
    <item>
      <title>When to Use HTTP PUT and HTTP POST</title>
      <link>https://sookocheff.com/post/api/when-to-use-http-put-and-http-post/</link>
      <pubDate>Thu, 27 Mar 2014 07:23:34 +0000</pubDate>
      <guid>https://sookocheff.com/post/api/when-to-use-http-put-and-http-post/</guid>
      <description>&lt;p&gt;The HTTP protocol defines two methods for updating a resource &amp;ndash; &lt;code&gt;PUT&lt;/code&gt; and
&lt;code&gt;POST&lt;/code&gt;. Both &lt;code&gt;PUT&lt;/code&gt; and &lt;code&gt;POST&lt;/code&gt; are used to modify a resource and this semantic
similarity can confuse API developers. This confusion has led most developers to
use &lt;code&gt;POST&lt;/code&gt; for any action which may modify the state of a resource, ignoring
&lt;code&gt;PUT&lt;/code&gt; entirely.&lt;/p&gt;
&lt;p&gt;This article attempts to explain the semantics behind the &lt;code&gt;PUT&lt;/code&gt; and &lt;code&gt;POST&lt;/code&gt;
methods and offers clear suggestions on when to use each method.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Stripe checkout opening in a new tab</title>
      <link>https://sookocheff.com/post/opinion/stripe-checkout-opening-in-a-new-tab/</link>
      <pubDate>Tue, 25 Mar 2014 07:23:45 +0000</pubDate>
      <guid>https://sookocheff.com/post/opinion/stripe-checkout-opening-in-a-new-tab/</guid>
      <description>&lt;p&gt;At &lt;a href=&#34;http://www.vendasta.com&#34;&gt;VendAsta&lt;/a&gt; we&amp;rsquo;ve been integrating with the &lt;a href=&#34;http://stripe.com/checkout&#34;&gt;Stripe&lt;/a&gt; payment system using Stripe Checkout. The experience has been completely painless and surprisingly simple. Then came a hiccup. While demoing the new functionality we found that one particular computer in the office would open the checkout modal dialog in a new browser window. Just one laptop. It was running the same version of Chrome that we were developing on. It was running the same OS as a working test machine. But the dialog would consistently open in a new browser window on just this one laptop.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How REST Constraints Affect API Design</title>
      <link>https://sookocheff.com/post/api/how-rest-constraints-affect-api-design/</link>
      <pubDate>Wed, 19 Mar 2014 14:11:48 +0000</pubDate>
      <guid>https://sookocheff.com/post/api/how-rest-constraints-affect-api-design/</guid>
      <description>&lt;p&gt;REST was developed and formalized by analyzing the existing Web and extracting
the principles that made it work. This set of principles was written down in the
&lt;a href=&#34;https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm&#34;&gt;Fielding dissertation&lt;/a&gt;
which lays out the set of constraints that, when enforced, will make a generic
network system into a resilient network like the Web. In Chapter 5 of the
dissertation Fielding outlines REST&amp;rsquo;s interface constraints.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;REST is defined by four interface constraints: identification of resources;
manipulation of resources using representations; self-descriptive messages;
and, hypermedia as the engine of application state.&lt;/p&gt;
&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>On choosing a hypermedia type for your API - HAL, JSON-LD, Collection&#43;JSON, SIREN, Oh My!</title>
      <link>https://sookocheff.com/post/api/on-choosing-a-hypermedia-format/</link>
      <pubDate>Tue, 11 Mar 2014 15:15:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/api/on-choosing-a-hypermedia-format/</guid>
      <description>&lt;p&gt;In recent years REST has been at the forefront of modern API
design. This has led to APIs with manageable URLs that respect the HTTP verbs
(GET, POST, PUT &lt;a href=&#34;http://www.w3.org/Protocols/rfc2616/rfc2616.html&#34;&gt;and the
rest&lt;/a&gt;), producing an
intuitive model for client developers. Unfortunately, there are two problems
that REST doesn&amp;rsquo;t solve alone.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Three questions that define an ideal customer</title>
      <link>https://sookocheff.com/post/business/three-questions-that-define-an-ideal-customer/</link>
      <pubDate>Sat, 04 Jan 2014 10:07:45 +0000</pubDate>
      <guid>https://sookocheff.com/post/business/three-questions-that-define-an-ideal-customer/</guid>
      <description>&lt;p&gt;One of the first steps in selling a new product or service is finding your target market and one of the best ways of finding your target market is by defining your ideal customer. Ask yourself &amp;ndash; out of all the people in the world who would be the most likely to buy this thing? If you can clearly answer this question you have your ideal customer and you can start a marketing campaign targetting exactly the demographic you are trying to sell to.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s go through an exercise that can help to find that ideal customer by asking three simple questions.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to get accepted to a business plan competition</title>
      <link>https://sookocheff.com/post/business/how-to-get-accepted-to-a-business-plan-competition/</link>
      <pubDate>Thu, 19 Dec 2013 09:09:09 +0000</pubDate>
      <guid>https://sookocheff.com/post/business/how-to-get-accepted-to-a-business-plan-competition/</guid>
      <description>&lt;p&gt;I recently received the good news that my business idea was accepted for the &lt;a href=&#34;http://www.usask.ca/research/ilo/business_plan.php&#34;&gt;University of Saskatchewan&amp;rsquo;s 2014 Tech Venture Challenge&lt;/a&gt;. The Tech Venture Challenge is a business plan competition for students and alumni where participants are judged by their finished business plan and pitch after a four month workshop program. I&amp;rsquo;m going to blog about the experience as a way to absorb the material and hopefully help someone else who may be applying in the future. This post will provide some admittedly biased advice on submitting your application to the Tech Venture Challenge.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Install node.js packages via npm with a Chef Cookbook</title>
      <link>https://sookocheff.com/post/javascript/node/install-npm-packages-with-a-chef-cookbook/</link>
      <pubDate>Thu, 06 Jun 2013 08:45:51 +0000</pubDate>
      <guid>https://sookocheff.com/post/javascript/node/install-npm-packages-with-a-chef-cookbook/</guid>
      <description>&lt;p&gt;I wanted to set up a Vagrant instance with node.js and some specific packages pre-installed. I found a Chef cookbook to install node and after a bit of work have a cookbook that will install arbitrary node packages through npm.  I based this heavily on &lt;a href=&#34;https://github.com/balbeko/chef-npm&#34;&gt;balbeko&lt;/a&gt;&amp;rsquo;s chef-npm cookbook with modifications to accept a data bag list of npm packages.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Photos is the Killer Feature of Google&#43;</title>
      <link>https://sookocheff.com/post/opinion/why-photos-is-the-killer-feature-of-google-plus/</link>
      <pubDate>Thu, 16 May 2013 16:17:18 +0000</pubDate>
      <guid>https://sookocheff.com/post/opinion/why-photos-is-the-killer-feature-of-google-plus/</guid>
      <description>&lt;p&gt;Yesterday&amp;rsquo;s &lt;a href=&#34;http://www.youtube.com/watch?feature=player_embedded&amp;amp;v=9pmPa_KxsAM&#34;&gt;Google I/O keynote&lt;/a&gt; unveiled some new features in Music, Maps and Search. But to me the biggest and most important announcement was the new &lt;a href=&#34;http://thenextweb.com/google/2013/05/15/googles-new-google-photo-features-15gb-full-size-storage-auto-highlight-auto-enhance-more/&#34;&gt;Google+ photo features&lt;/a&gt;. Full-size high-resolution photos, automatic highlights of entire albums, automatic enhancement and auto-awesome combine to make Google+ &lt;em&gt;the&lt;/em&gt; most feature packed photo hosting service on the web. Add the ability to share pictures with anyone via e-mail (take that Facebook) and Google+ is now &lt;em&gt;the&lt;/em&gt; best social network to host and share photos.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Apple has a Software Problem - Why I&#39;ll be Switching to Android</title>
      <link>https://sookocheff.com/post/opinion/apple-has-a-software-problem-why-ill-be-switching-to-android/</link>
      <pubDate>Tue, 30 Apr 2013 22:10:18 +0000</pubDate>
      <guid>https://sookocheff.com/post/opinion/apple-has-a-software-problem-why-ill-be-switching-to-android/</guid>
      <description>&lt;p&gt;No one can question Apple’s dominance in hardware. The build quality and user experience of the iPod, iPhone and iPad positioned Apple as the most profitable company in the world. However, with the build quality of rival devices quickly approaching Apple quality, software will be the next battleground for consumer loyalty. And Apple has a software problem.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Creating a new file or directory in Vim using NERDTree</title>
      <link>https://sookocheff.com/post/vim/creating-a-new-file-or-directoryin-vim-using-nerdtree/</link>
      <pubDate>Fri, 19 Apr 2013 12:18:19 +0000</pubDate>
      <guid>https://sookocheff.com/post/vim/creating-a-new-file-or-directoryin-vim-using-nerdtree/</guid>
      <description>&lt;p&gt;I’m not sure why this was so difficult to discover. For the longest time I was not sure how to create a new file using NERDTree. I finally sat down and figure out how it works.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Submitting a Unity3d Game to the Mac App Store</title>
      <link>https://sookocheff.com/post/unity/submitting-a-unity3d-game-to-the-mac-app-store/</link>
      <pubDate>Tue, 09 Apr 2013 14:43:12 +0000</pubDate>
      <guid>https://sookocheff.com/post/unity/submitting-a-unity3d-game-to-the-mac-app-store/</guid>
      <description>&lt;p&gt;Submitting a Unity3d game to the Mac App Store is a somewhat painful process. This guide refers to Unity3d 3.5 but should apply to Unity 4.0 and up.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Copying from Vim to the OS X Mountain Lion clipboard</title>
      <link>https://sookocheff.com/post/vim/copying-from-the-vim-to-the-os-x-mountain-lion-clipboard/</link>
      <pubDate>Tue, 22 Jan 2013 08:16:42 +0000</pubDate>
      <guid>https://sookocheff.com/post/vim/copying-from-the-vim-to-the-os-x-mountain-lion-clipboard/</guid>
      <description>&lt;p&gt;The latest version of OS X (Mountain Lion) broke compatibility with the vim and the OS clipboard. In most cases you can configure vim to use the operating system clipboard by setting &lt;code&gt;clipboard=unnamed&lt;/code&gt; in your &lt;code&gt;.vimrc&lt;/code&gt;. Unfortunately this setting does not work in OS X because the default version of vim was not compiled with clipboard support. You can check if your version of vim is compiled with clipboard support by typing &lt;code&gt;vim –version&lt;/code&gt;  and looking for &lt;code&gt;clipboard&lt;/code&gt;. A prepended &lt;code&gt;+&lt;/code&gt; means support is enabled. A prepended &lt;code&gt;–&lt;/code&gt; means support is disabled.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Showing a local webpage in Unity3d using the Prime[31] etcetera plugin.</title>
      <link>https://sookocheff.com/post/unity/etcetera-plugin-live-alerts-prompts-loading-views-push-localization-and-more/</link>
      <pubDate>Thu, 15 Nov 2012 13:14:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/unity/etcetera-plugin-live-alerts-prompts-loading-views-push-localization-and-more/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been working with Prime31&amp;rsquo;s Etcetera plugin for iOS development with
Unity3d. There are a lot of great things in there but some of the documentation
is lacking.  Anyways, if you want to show a local web page with the
&lt;code&gt;showWebPage&lt;/code&gt; command it is a two step process.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Using Unity3d with Version Control</title>
      <link>https://sookocheff.com/post/unity/using-unity3d-with-version-control/</link>
      <pubDate>Mon, 08 Oct 2012 09:11:18 +0000</pubDate>
      <guid>https://sookocheff.com/post/unity/using-unity3d-with-version-control/</guid>
      <description>&lt;p&gt;I had a tough time finding this page. The steps to get Unity set up with version control aren’t that difficult but it is one of those problems that you need to be told how to solve.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Saving canvas data to an image file with JavaScript and PHP</title>
      <link>https://sookocheff.com/post/javascript/saving-canvas-data-to-an-image-file-with-javascript-and-php/</link>
      <pubDate>Wed, 27 Jul 2011 10:08:42 +0000</pubDate>
      <guid>https://sookocheff.com/post/javascript/saving-canvas-data-to-an-image-file-with-javascript-and-php/</guid>
      <description>&lt;p&gt;Saving HTML canvas element data to an image in a user friendly manner is a tricky problem. Let&amp;rsquo;s look at one way to solve it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Using Leiningen behind a Windows proxy</title>
      <link>https://sookocheff.com/post/clojure/using-leiningen-behind-a-windows-proxy/</link>
      <pubDate>Tue, 28 Jun 2011 11:15:08 +0000</pubDate>
      <guid>https://sookocheff.com/post/clojure/using-leiningen-behind-a-windows-proxy/</guid>
      <description>&lt;p&gt;I’ve been getting familiar with the &lt;a href=&#34;https://github.com/technomancy/leiningen&#34;&gt;Leiningen&lt;/a&gt; build tool for &lt;a href=&#34;http://clojure.org/&#34;&gt;Clojure&lt;/a&gt; but had trouble connecting to the Clojar and Maven repositories behind a proxy.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Date.now() in IE6</title>
      <link>https://sookocheff.com/post/javascript/date-now-in-ie6/</link>
      <pubDate>Thu, 09 Jun 2011 11:10:09 +0000</pubDate>
      <guid>https://sookocheff.com/post/javascript/date-now-in-ie6/</guid>
      <description>&lt;p&gt;I was fiddling with a JavaScript timer application and noticed a bug in IE6. I’m sure this is documented elsewhere but I couldn’t find anything with some quick searches; hence this post.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The JavaScript click event and hidden input elements</title>
      <link>https://sookocheff.com/post/javascript/the-javascript-click-event-and-hidden-input-elements/</link>
      <pubDate>Thu, 02 Jun 2011 16:42:48 +0000</pubDate>
      <guid>https://sookocheff.com/post/javascript/the-javascript-click-event-and-hidden-input-elements/</guid>
      <description>&lt;p&gt;I was recently working with the HTML canvas element and wanted to attach an event to the canvas that would fire the click event of a file input element. I would then hide the input element so that the canvas element was the only way to browse for files.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Dissecting jQuery&#39;s Fade Animation</title>
      <link>https://sookocheff.com/post/javascript/dissecting-jquerys-fade-animation/</link>
      <pubDate>Wed, 18 May 2011 15:16:17 +0000</pubDate>
      <guid>https://sookocheff.com/post/javascript/dissecting-jquerys-fade-animation/</guid>
      <description>&lt;p&gt;Fade animations are a standard tool in any jQuery developer’s toolbox. But how do they really work? Let’s create a small function that encapsulates solely the fade functionality and find out.&lt;/p&gt;</description>
    </item>
    <item>
      <title>An Argument Against JavaScript Minification</title>
      <link>https://sookocheff.com/post/opinion/an-argument-against-javascript-minification/</link>
      <pubDate>Tue, 10 May 2011 15:11:09 +0000</pubDate>
      <guid>https://sookocheff.com/post/opinion/an-argument-against-javascript-minification/</guid>
      <description>&lt;p&gt;Developers learn by example. This is no secret. The first advice given to new developers is to read a lot of good source code and the best advice given to experienced developers is to read a lot of good source code. Canonical texts for many languages let the source code say far more than the text. I’m thinking of text’s like &lt;a href=&#34;http://amzn.to/2kTIZYW&#34;&gt;Kernighan &amp;amp; Ritchie&lt;/a&gt; and &lt;a href=&#34;http://mitpress.mit.edu/catalog/item/default.asp?ttype=2&amp;amp;tid=4825&#34;&gt;Friedman &amp;amp; Felleisen&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to Display HTML5 Notifications</title>
      <link>https://sookocheff.com/post/javascript/how-to-display-html5-notifications/</link>
      <pubDate>Fri, 06 May 2011 10:10:10 +0000</pubDate>
      <guid>https://sookocheff.com/post/javascript/how-to-display-html5-notifications/</guid>
      <description>&lt;p&gt;Chrome recently introduced support for HTML Notifications.&lt;/p&gt;
&lt;p&gt;Following the brief tutorial at &lt;a href=&#34;http://www.html5rocks.com/tutorials/notifications/quick/&#34;&gt;HTML5 Rocks&lt;/a&gt; I was able to implement this in a matter of minutes and I couldn’t be happier with the results.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Constants in JavaScript</title>
      <link>https://sookocheff.com/post/javascript/constants-in-javascript/</link>
      <pubDate>Wed, 20 Apr 2011 14:11:28 +0000</pubDate>
      <guid>https://sookocheff.com/post/javascript/constants-in-javascript/</guid>
      <description>&lt;p&gt;How are constants declared in JavaScript?&lt;/p&gt;</description>
    </item>
    <item>
      <title>Understanding Closures in JavaScript</title>
      <link>https://sookocheff.com/post/javascript/understanding-closures-in-javascript/</link>
      <pubDate>Wed, 19 Jan 2011 09:11:15 +0000</pubDate>
      <guid>https://sookocheff.com/post/javascript/understanding-closures-in-javascript/</guid>
      <description>&lt;p&gt;Closures are easy. There I said it. Invest a little bit of time, and you will say it too. Follow along with me as I attempt to explain what closures are and how they are used.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Safely remove the header from the WordPress TwentyTen theme</title>
      <link>https://sookocheff.com/post/tools/safely-remove-the-header-from-the-wordpress-twentyten-theme/</link>
      <pubDate>Tue, 18 Jan 2011 10:11:12 +0000</pubDate>
      <guid>https://sookocheff.com/post/tools/safely-remove-the-header-from-the-wordpress-twentyten-theme/</guid>
      <description>&lt;p&gt;WordPress’ new TwentyTen theme is terrific. Well supported, highly modifiable, and with tons of widgets to get the exact layout you desire right out of the box. However, one thing I didn’t like too much was having a big header image on the page. I’m a bit of a minimalist so I wanted to trim down the theme by removing the banner image and the navigation bar.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The future of mobile development</title>
      <link>https://sookocheff.com/post/mobile/the-future-of-mobile-development/</link>
      <pubDate>Sat, 15 Jan 2011 09:19:21 +0000</pubDate>
      <guid>https://sookocheff.com/post/mobile/the-future-of-mobile-development/</guid>
      <description>&lt;p&gt;The future of mobile development is cross-platform HTML5, JavaScript, and CSS3.  Let me explain. I’ve been working on a couple Windows Phone 7 applications to accompany my first release, &lt;a href=&#34;http://www.appsfuze.com/applications/windowsphone.photo/faceart,3617&#34;&gt;FaceArt&lt;/a&gt;, in the Marketplace. As I do more research and development with the mobile platform I keep looking for ways to increase the reach of my apps. The most obvious is to release Android and iOS versions but I have a few hurdles to clear first, the biggest being lack of time. I do all development as a moonlighting gig while I work full-time and I’m already struggling to find extra hours during the week to finish my first three applications for one platform. How am I going to write and maintain three separate codebases for each app for the major mobile platforms while still keeping my employer happy during the work week?  The solution is cross-platform libraries targeting mobile and web apps. &lt;a href=&#34;http://www.phonegap.com&#34;&gt;PhoneGap&lt;/a&gt;, &lt;a href=&#34;http://www.airplaysdk.com&#34;&gt;AirPlay&lt;/a&gt;, and &lt;a href=&#34;http://www.dragonfiresdk.com&#34;&gt;DragonFire SDK&lt;/a&gt; are a few notable products designed for just this problem.  The most notable, and most intriguing for me, is PhoneGap. I first noticed PhoneGap through an article on &lt;a href=&#34;http://arstechnica.com/apple/news/2010/11/introducing-the-ars-technica-reader-for-ipad.ars&#34;&gt;ArsTechnica&lt;/a&gt;. This open-source solution wraps apps designed with HTML5, JavaScript, and CSS in a container suitable for the respective app stores. Why is this exciting? You can design an application for the web and get the mobile app for free (or minimal) time investment.  This is as close to the write once, run anywhere ideal that we will get for mobile phones and as the tools improve the experience is only going to get better for developers.  I personally can’t wait to see what the future holds for this product. What do you think?&lt;/p&gt;</description>
    </item>
    <item>
      <title>A cheap home server</title>
      <link>https://sookocheff.com/post/linux/a-cheap-home-server/</link>
      <pubDate>Tue, 11 Jan 2011 06:55:12 +0000</pubDate>
      <guid>https://sookocheff.com/post/linux/a-cheap-home-server/</guid>
      <description>&lt;p&gt;In order to have a home server you need the server.  That is, you need the hardware.  You could probably find all sorts of information comparing performance, power consumption, and cost for an assortment of different parts (check &lt;a href=&#34;http://www.tomshardware.com&#34;&gt;tomshardware.com&lt;/a&gt; or do some intense [Googling][2]).  Or, you can trust that I’ve done my research and go with the same setup as me.&lt;/p&gt;</description>
    </item>
    <item>
      <title>And the winner is - Google Chrome!</title>
      <link>https://sookocheff.com/post/opinion/and-the-winner-is-google-chrome/</link>
      <pubDate>Thu, 06 Jan 2011 15:23:34 +0000</pubDate>
      <guid>https://sookocheff.com/post/opinion/and-the-winner-is-google-chrome/</guid>
      <description>&lt;p&gt;Google gets it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to install the real-time kernel in Ubuntu</title>
      <link>https://sookocheff.com/post/linux/how-to-install-the-real-time-kernel-in-ubuntu/</link>
      <pubDate>Tue, 19 Oct 2010 15:09:18 +0000</pubDate>
      <guid>https://sookocheff.com/post/linux/how-to-install-the-real-time-kernel-in-ubuntu/</guid>
      <description>&lt;p&gt;To use Ubuntu as an audio production server you need the real-time kernel. This allows applications to have some guarantee of the maximum response time of any task. High priority tasks are given the CPU within a fixed minimum amount of time allowing for processor intensive tasks to actually be completed. Follow along to see how to install the real-time kernel yourself. A vanilla install of most Linux distributions does not enable the real-time kernel, but it is easy enough to install.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to get Pulse Audio to recognize your Delta 44 (and other ICE1712 cards)</title>
      <link>https://sookocheff.com/post/linux/how-to-get-pulse-audio-to-recognize-your-delta-44-and-other-ice1712-cards/</link>
      <pubDate>Tue, 28 Sep 2010 14:23:34 +0000</pubDate>
      <guid>https://sookocheff.com/post/linux/how-to-get-pulse-audio-to-recognize-your-delta-44-and-other-ice1712-cards/</guid>
      <description>&lt;p&gt;I bought a used Delta 44 soundcard with the intention of recording my guitar playing. Pairing this with Rockit 5 powered monitors, a Mackie 802-VLZ3 mixer and the classic Shure SM57 microphone made for a good quality, inexpensive home studio. Using the PCI-based Delta 44 meant that any old computer would work and my idea was to use vanilla Ubuntu and install the Ardour digital audio workstation to push costs even further down. So far so good. Now the only issue is getting everything up and running. Ubuntu is a fairly mature distribution; you can expect a certain level of quality with each release. Unfortunately, this has not been the case with PulseAudio. I won’t go into details; suffice it to say it had a tumultuous upbringing and many of the kinks have since been worked out. Anyways, I quickly discovered that PulseAudio does not recognize the Delta 44. Don’t worry, this is a known problem and a workaround exists. Finding the workaround, however, did take some time.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Readability by Arc90</title>
      <link>https://sookocheff.com/post/tools/readability-by-arc90/</link>
      <pubDate>Sat, 04 Sep 2010 13:13:13 +0000</pubDate>
      <guid>https://sookocheff.com/post/tools/readability-by-arc90/</guid>
      <description>&lt;p&gt;According to Wikipedia, readability is defined as reading ease, especially as it results from a writing style.  Only experience, practice, and hard work can improve a person’s writing style.  Let’s increase readability in a different manner: with typography.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Share multiple mt-daap libraries</title>
      <link>https://sookocheff.com/post/linux/share-multiple-mt-daap-libraries/</link>
      <pubDate>Tue, 03 Aug 2010 18:12:34 +0000</pubDate>
      <guid>https://sookocheff.com/post/linux/share-multiple-mt-daap-libraries/</guid>
      <description>&lt;p&gt;I recently moved all of our household music to a shared network drive and was looking for a solution to stream these libraries as distinct entities; I wanted to keep my wife’s library separate mostly so I could keep all of my painstakingly catalouged music organized exactly how I like it. I was already using mt-daapd, now known as the Firefly Media Server, to stream my own library from my Linux server. Unfortunately, it doesn’t support streaming two libraries from one program instance. The solution to this is to run two copies of mt-daapd and configure them to play nice with each other. Don’t worry, it’s not quite as difficult as it sounds. The first thing you’ll need is to have a separate configuration file for the second daap instance. The easiest way to do this is to copy the files from an existing installation.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Mounting SAMBA shares from the command line</title>
      <link>https://sookocheff.com/post/linux/mounting-samba-shares-from-the-command-line/</link>
      <pubDate>Wed, 28 Jul 2010 18:12:37 +0000</pubDate>
      <guid>https://sookocheff.com/post/linux/mounting-samba-shares-from-the-command-line/</guid>
      <description>&lt;p&gt;I recently started using Xubuntu to see if the proclaimed speed differences actually made a difference in productivity. Unfortunately, the Thunar file manager does not automatically recognize network drives so I needed to manually mount SAMBA shares from the command line.  In my searches I stumbled across this &lt;a href=&#34;http://ubuntuforums.org/showthread.php?t=288534&#34;&gt;thread&lt;/a&gt; giving the exact solution I used.  Hopefully this helps someone else who is having this same problem.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to forward root users mail to an external address</title>
      <link>https://sookocheff.com/post/linux/how-to-forward-root-users-mail-to-an-external-address/</link>
      <pubDate>Tue, 01 Jun 2010 14:12:32 +0000</pubDate>
      <guid>https://sookocheff.com/post/linux/how-to-forward-root-users-mail-to-an-external-address/</guid>
      <description>&lt;p&gt;I recently set up a RAID array wanted to keep notified of any errors that may occur. By default Ubuntu Server sends mail to the root user whenever an error occurs but logging in as root to check mail every so often didn’t seem very convenient. There had to be a better way. The best information that I found came from the Ubuntu community forums. Here I’ll expand on that discussion, hopefully helping other people who are trying to do the same thing. The traditional way to forward mail is to create a .forward file in your home directory, entering the addresses that you would like to forward mail to.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to monitor a RAID array in Ubuntu server</title>
      <link>https://sookocheff.com/post/linux/how-to-monitor-a-raid-array-in-ubuntu-server/</link>
      <pubDate>Fri, 28 May 2010 02:15:45 +0000</pubDate>
      <guid>https://sookocheff.com/post/linux/how-to-monitor-a-raid-array-in-ubuntu-server/</guid>
      <description>&lt;p&gt;I’ve been searching for a way to reliably monitor a RAID array.  I found a few resources and decided to compile them in one post.  If you are running Ubuntu Server skip to the bottom for some good news.&lt;/p&gt;</description>
    </item>
    <item>
      <title>AI Ethics</title>
      <link>https://sookocheff.com/ai-ethics/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://sookocheff.com/ai-ethics/</guid>
      <description>&lt;p&gt;This blog is written by me, Kevin Sookocheff, without AI assistance.
I will not publish anything that takes you longer to read than it took me
to write.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The act of writing does many things.&lt;/p&gt;
&lt;p&gt;It forces you to slow down, focus your attention, and think deeply. It
uncovers gaps in your thinking. It refines and clarifies your position.
And you almost always learn and discover something new in the process.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
