<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.8.6">Jekyll</generator><link href="https://penelope.zone/feed.xml" rel="self" type="application/atom+xml" /><link href="https://penelope.zone/" rel="alternate" type="text/html" /><updated>2020-05-06T17:47:09+00:00</updated><id>https://penelope.zone/feed.xml</id><title type="html">penelope.zone</title><subtitle>I do spooky things with computers. Sometimes they work, sometimes they don't. She/her ⋃ trans ⋃ queer. Body temperature too low. Don't call me Penny.</subtitle><author><name>{&quot;twitter&quot;=&gt;&quot;penelope_zone&quot;}</name></author><entry><title type="html">A silly thing you can do with the Ruby parser</title><link href="https://penelope.zone/2019/12/22/a-silly-thing-you-can-do-with-the-ruby-parser.html" rel="alternate" type="text/html" title="A silly thing you can do with the Ruby parser" /><published>2019-12-22T00:00:00+00:00</published><updated>2019-12-22T00:00:00+00:00</updated><id>https://penelope.zone/2019/12/22/a-silly-thing-you-can-do-with-the-ruby-parser</id><content type="html" xml:base="https://penelope.zone/2019/12/22/a-silly-thing-you-can-do-with-the-ruby-parser.html">&lt;p&gt;Here’s a silly thing you can do with the Ruby parser:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;omg&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Box&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;
     &lt;span class=&quot;nb&quot;&gt;attr_accessor&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:contents&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;contents&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;contents&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;omg&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;you-what&quot;&gt;You… what?&lt;/h2&gt;

&lt;p&gt;So let’s break this down. In Ruby, the way one catches exceptions is with a
&lt;code class=&quot;highlighter-rouge&quot;&gt;begin...rescue...end&lt;/code&gt; expression. The &lt;code class=&quot;highlighter-rouge&quot;&gt;rescue&lt;/code&gt; part of that looks like this:
&lt;code class=&quot;highlighter-rouge&quot;&gt;rescue &amp;lt;class_name&amp;gt; =&amp;gt; &amp;lt;assignable_expression&amp;gt;&lt;/code&gt;. Usually you’d see something
like:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;whatever&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SomeClass&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;some_local_variable_name&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;do_something_with_local_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;some_local_variable_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;However, it doesn’t have to be this way. In fact, the Ruby parser permits any
valid assignment expression in Ruby! So we can for example set a key in a hash
from a rescue:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;omg&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:the_key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;inspect&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; {:the_key=&amp;gt;#&amp;lt;RuntimeError: omg&amp;gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So, to come back to our first example:&lt;/p&gt;
&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;omg&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Box&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;
     &lt;span class=&quot;nb&quot;&gt;attr_accessor&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:contents&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;contents&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;contents&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;omg&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here we, &lt;strong&gt;in the rescue clause&lt;/strong&gt;, define a class called box, define a class
level attribute called contents, and then set it. You shouldn’t ever do this in
you production code, but it is possible.&lt;/p&gt;

&lt;h2 id=&quot;why-is-this-even-possible&quot;&gt;Why is this even possible?&lt;/h2&gt;

&lt;p&gt;As far as I can tell, the reason why this works as it does has to do with the
history of the implementation of Ruby. Before Ruby 1.9, Ruby used a “tree
walking” interpreter. This means that Ruby code was executed from the syntax
tree of the program, with no intermediate steps. Putting the rescued exception
“somewhere”, conceptually, is the same thing as variable assignment, even though
it doesn’t look like &lt;code class=&quot;highlighter-rouge&quot;&gt;local_name =&lt;/code&gt;, so the code was shared between rescue and
variable assignment.&lt;/p&gt;

&lt;p&gt;Neat!&lt;/p&gt;

&lt;p&gt;If you enjoyed this post, please consider sending me a follow on twitter:
&lt;a href=&quot;https://twitter.com/penelope_zone&quot;&gt;@penelope_zone&lt;/a&gt;.&lt;/p&gt;</content><author><name>{&quot;twitter&quot;=&gt;&quot;penelope_zone&quot;}</name></author><summary type="html">Here’s a silly thing you can do with the Ruby parser:</summary></entry><entry><title type="html">What’s next for Rubyfmt?</title><link href="https://penelope.zone/2019/11/26/whats-next-for-rubyfmt.html" rel="alternate" type="text/html" title="What's next for Rubyfmt?" /><published>2019-11-26T00:00:00+00:00</published><updated>2019-11-26T00:00:00+00:00</updated><id>https://penelope.zone/2019/11/26/whats-next-for-rubyfmt</id><content type="html" xml:base="https://penelope.zone/2019/11/26/whats-next-for-rubyfmt.html">&lt;p&gt;So today I was (happily) able to announce that the Rubyfmt unit suite is working in the Rust backend. This is a huge
milestone for the library, but I also wanted to take a little time to talk about what’s next.&lt;/p&gt;

&lt;h2 id=&quot;implement-a-few-remaining-syntax-nodes&quot;&gt;Implement a few remaining syntax nodes&lt;/h2&gt;

&lt;p&gt;The Rubyfmt &lt;a href=&quot;https://github.com/penelopezone/rubyfmt/tree/master/fixtures&quot;&gt;unit suite&lt;/a&gt; is designed to be a comprehensive set of programs that show a minimal use of every possible node
in Ruby’s grammar. I definitely missed a few while building out the first implementation, and this is evidenced quickly
while running on larger programs. I’ll be working through filling those gaps as the next priority. I’m also intending to
remove one very large program (&lt;code class=&quot;highlighter-rouge&quot;&gt;rspec_core_notifications_actual&lt;/code&gt; copied directly from RSpec’s source code). I’ll be
replacing that with a full execution over the RSpec source code&lt;/p&gt;

&lt;h2 id=&quot;fixup-renderer&quot;&gt;“fixup” renderer&lt;/h2&gt;

&lt;p&gt;Right now the Rubyfmt architecture is designed to walk a 
&lt;a href=&quot;https://ruby-doc.org/stdlib-2.5.1/libdoc/ripper/rdoc/Ripper.html&quot;&gt;Ripper&lt;/a&gt; syntax tree and produce a queue of tokens.
Those tokens have a “naieve” stringification. This naieve stringification prints very ugly Ruby programs. The pure
Ruby architecture features a backend called “fixup” which introspects groups of those tokens to actually nice syntax.
I need to implement that before anyone can get their hands on it.&lt;/p&gt;

&lt;h2 id=&quot;proper-integration-between-the-ruby-program-and-the-rust-library&quot;&gt;Proper integration between the Ruby program and the Rust library&lt;/h2&gt;

&lt;p&gt;What I have right now is a total hack to just make something work. In order to be release worthy we need a story around
integrating the &lt;code class=&quot;highlighter-rouge&quot;&gt;Rubyfmt&lt;/code&gt; rust library and the Ruby shell.&lt;/p&gt;

&lt;h2 id=&quot;ci--builds--qa&quot;&gt;CI / builds / QA&lt;/h2&gt;

&lt;p&gt;Right now the CI for rubyfmt is totally busted, and based on a beta of GitHub actions. I’ll be moving that to a more modern
version of GitHub actions and doing things like automating rust compilation and clippy checks.&lt;/p&gt;

&lt;h2 id=&quot;first-things-first&quot;&gt;First things first&lt;/h2&gt;

&lt;p&gt;My first milestone will be the same as the pure Ruby version of Rubyfmt. Getting the &lt;a href=&quot;https://github.com/rspec/rspec-core&quot;&gt;RSpec Core&lt;/a&gt;
test suite passing against formatted files. Once that’s done, we then move on to ensuring the formatted code looks good
in most scenarios, and aim towards our next release.&lt;/p&gt;

&lt;p&gt;You shouldn’t expect that any time right soon, as there’s plenty of work still to do. I appreciate, however, you following
along for the journey. As always, day to day updates can be found on my twitter: &lt;a href=&quot;https://twitter.com/penelope_zone&quot;&gt;@penelope_zone&lt;/a&gt;&lt;/p&gt;</content><author><name>{&quot;twitter&quot;=&gt;&quot;penelope_zone&quot;}</name></author><summary type="html">So today I was (happily) able to announce that the Rubyfmt unit suite is working in the Rust backend. This is a huge milestone for the library, but I also wanted to take a little time to talk about what’s next.</summary></entry><entry><title type="html">Retiring from RSpec Core</title><link href="https://penelope.zone/2019/10/07/retiring-from-rspec-core.html" rel="alternate" type="text/html" title="Retiring from RSpec Core" /><published>2019-10-07T00:00:00+00:00</published><updated>2019-10-07T00:00:00+00:00</updated><id>https://penelope.zone/2019/10/07/retiring-from-rspec-core</id><content type="html" xml:base="https://penelope.zone/2019/10/07/retiring-from-rspec-core.html">&lt;p&gt;Hi Folks,&lt;/p&gt;

&lt;p&gt;I’ll keep this one short and sweet. As of a little while ago, I messaged the
other RSpec maintainers to let them know that I’d like to move on from the
project, instead focusing on &lt;a href=&quot;https://github.com/penelopezone/rubyfmt&quot;&gt;rubyfmt&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Many people don’t know this, but I essentially got started programming Ruby by
working on RSpec. This has given me a very different perspective on how to work
on Ruby than most folks I meet. I owe many parts of my career to the work that I
did there and the help I got from the others getting started. Especially David,
Andy, and Myron. It’s been a fun several years, but as of now, I’m no longer
describing myself as “on the RSpec core team”.&lt;/p&gt;

&lt;p&gt;Thanks :)&lt;/p&gt;</content><author><name>{&quot;twitter&quot;=&gt;&quot;penelope_zone&quot;}</name></author><summary type="html">Hi Folks,</summary></entry><entry><title type="html">Minimum viable example of calling Rust from Ruby without a gem.</title><link href="https://penelope.zone/2019/07/13/minimum-viable-gem-free-calling-rust-from-ruby-example.html" rel="alternate" type="text/html" title="Minimum viable example of calling Rust from Ruby without a gem." /><published>2019-07-13T16:39:13+00:00</published><updated>2019-07-13T16:39:13+00:00</updated><id>https://penelope.zone/2019/07/13/minimum-viable-gem-free-calling-rust-from-ruby-example</id><content type="html" xml:base="https://penelope.zone/2019/07/13/minimum-viable-gem-free-calling-rust-from-ruby-example.html">&lt;p&gt;For &lt;a href=&quot;https://github.com/penelopezone&quot;&gt;Rubyfmt&lt;/a&gt; I’m currently looking at rewriting
significant sections in Rust, because there’s some performance issues. Broadly
speaking, it turns out that cleaning up a very large Ruby parse tree (e.g. 4000
lines) can be slow because of the number of comparisons that have to be made.
Rust can do this a lot faster.&lt;/p&gt;

&lt;p&gt;See &lt;a href=&quot;https://github.com/penelopezone/rubysoexperiment&quot;&gt;https://github.com/penelopezone/rubysoexperiment&lt;/a&gt;  if you’d like to try it out yourself.&lt;/p&gt;

&lt;h2 id=&quot;starting-with-rust&quot;&gt;Starting with Rust&lt;/h2&gt;

&lt;p&gt;To start with, let’s imagine that I’ve got this rust function that I want to
call from Ruby:&lt;/p&gt;

&lt;!--kg-card-begin: code--&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pub fn return_3() -&amp;gt; i32 {
  return 3;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;!--kg-card-end: code--&gt;

&lt;p&gt;First, we’ll need to prepare it to be used outside of Rust. By default the Rust
Compiler will rename functions, and also make them incompatible with non-rust
languages in order to be able to perform various kinds of optimisations. I
makes a lot sense that the default is optimised for pure rust, but that’s no
what we’re doing today.&lt;/p&gt;

&lt;p&gt;So, I’ll rewrite my function like this:&lt;/p&gt;

&lt;!--kg-card-begin: code--&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#[no_mangle]
pub extern fn return_3() -&amp;gt; i32 {
    return 3;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;!--kg-card-end: code--&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;#[no_mangle]&lt;/code&gt; means that the name is preserved for calling in c (or really any
language that can load functions from a native library), &lt;code class=&quot;highlighter-rouge&quot;&gt;extern&lt;/code&gt; means that
it’ll be exported for use from whatever we compile.&lt;/p&gt;

&lt;p&gt;Now we’ll need to modify our &lt;code class=&quot;highlighter-rouge&quot;&gt;Cargo.toml&lt;/code&gt; to allow us to build a static library,
that we can compile in to our Ruby extension eventually:&lt;/p&gt;

&lt;!--kg-card-begin: code--&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[package]
name = &quot;rubysoexperiment&quot;
version = &quot;0.1.0&quot;
authors = [&quot;Sam Phippen &amp;lt;penelopezone@googlemail.com&amp;gt;&quot;]
edition = &quot;2018&quot;

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
[lib]
name = &quot;foo&quot;
crate-type = [&quot;staticlib&quot;]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;!--kg-card-end: code--&gt;

&lt;p&gt;Once we do &lt;code class=&quot;highlighter-rouge&quot;&gt;cargo build&lt;/code&gt;, we’ll now see that &lt;code class=&quot;highlighter-rouge&quot;&gt;target/debug&lt;/code&gt; contains a file
called &lt;code class=&quot;highlighter-rouge&quot;&gt;libfoo.a&lt;/code&gt;. &lt;code class=&quot;highlighter-rouge&quot;&gt;.a&lt;/code&gt; means that the file is a collection of native functions
that can be called by other languages, but must be compiled in with whatever
program is going to call those functions (AKA a static library).&lt;/p&gt;

&lt;h2 id=&quot;making-return_3-available-to-ruby&quot;&gt;Making &lt;code class=&quot;highlighter-rouge&quot;&gt;return_3&lt;/code&gt; available to Ruby&lt;/h2&gt;

&lt;p&gt;Ruby’s primitive types like &lt;code class=&quot;highlighter-rouge&quot;&gt;Fixnum&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;String&lt;/code&gt;, etc aren’t C or Rust types by
default, but rather are Ruby objects. The C type for these is called &lt;code class=&quot;highlighter-rouge&quot;&gt;VALUE&lt;/code&gt;,
which Ruby uses as a type under the hood to wrap every type of object that it
can represent. So, we need a function that can call &lt;code class=&quot;highlighter-rouge&quot;&gt;return_3&lt;/code&gt; in a Ruby
compatible way. We’ll do this in C so it can be more easily compiled in to a
Ruby extension:&lt;/p&gt;

&lt;!--kg-card-begin: code--&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#include &amp;lt;ruby.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;

extern int32_t return_3();

VALUE foo_rb_return_3(VALUE klass) {
    int32_t three = return_3();
    return LONG2FIX(three);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;!--kg-card-end: code--&gt;

&lt;p&gt;This block of C includes &lt;code class=&quot;highlighter-rouge&quot;&gt;ruby.h&lt;/code&gt;, a C header file that gives us various
functions to work with the Ruby interpreter, and &lt;code class=&quot;highlighter-rouge&quot;&gt;stdint.h&lt;/code&gt;, which declares
fixed width integer types (in this case we need &lt;code class=&quot;highlighter-rouge&quot;&gt;int32_t&lt;/code&gt;, because we declared
our function to be an &lt;code class=&quot;highlighter-rouge&quot;&gt;i32&lt;/code&gt; in Rust). It then declares that &lt;code class=&quot;highlighter-rouge&quot;&gt;return_3&lt;/code&gt; is a
function from outside of the C file (because it’s declared in Rust). Then it
declares the function &lt;code class=&quot;highlighter-rouge&quot;&gt;foo_rb_return_3&lt;/code&gt;, which calls &lt;code class=&quot;highlighter-rouge&quot;&gt;return_3&lt;/code&gt;, and then wraps
it in the &lt;code class=&quot;highlighter-rouge&quot;&gt;LONG2FIX&lt;/code&gt; macro. This macro comes from &lt;code class=&quot;highlighter-rouge&quot;&gt;ruby.h&lt;/code&gt; and converts a C
&lt;code class=&quot;highlighter-rouge&quot;&gt;int32&lt;/code&gt; (really any numeric type) in to a Ruby &lt;code class=&quot;highlighter-rouge&quot;&gt;Fixnum&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;making-this-file-a-ruby-extension&quot;&gt;Making this file a Ruby extension.&lt;/h2&gt;

&lt;p&gt;Now that we’ve done that, we need to do a few more things to make this C file a
valid Ruby extension. When Ruby loads native extensions it calls
&lt;code class=&quot;highlighter-rouge&quot;&gt;Init_&amp;lt;libraryname&amp;gt;&lt;/code&gt;, which for us is going to be &lt;code class=&quot;highlighter-rouge&quot;&gt;Init_foo&lt;/code&gt;. So let’s define
that function:&lt;/p&gt;

&lt;!--kg-card-begin: code--&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#include &amp;lt;ruby.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;

extern int32_t return_3();

VALUE foo_rb_module_foo = Qnil;

VALUE foo_rb_return_3(VALUE klass) {
    int32_t three = return_3();
    return LONG2FIX(three);
}

void Init_foo(void) {
    foo_rb_module_foo = rb_define_module(&quot;Foo&quot;);
    rb_define_module_function(foo_rb_module_foo, &quot;return_3&quot;, foo_rb_return_3, 0);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;!--kg-card-end: code--&gt;

&lt;p&gt;We’ve made a few changes here. Firstly, we’ve defined a new variable:
&lt;code class=&quot;highlighter-rouge&quot;&gt;VALUE foo_rb_module_foo = Qnil&lt;/code&gt;. This is essentially declaring that we have a
new Ruby object called &lt;code class=&quot;highlighter-rouge&quot;&gt;foo_rb_module_foo&lt;/code&gt;. When &lt;code class=&quot;highlighter-rouge&quot;&gt;Init_foo&lt;/code&gt; is called, we call
&lt;code class=&quot;highlighter-rouge&quot;&gt;foo_rb_module_foo = rb_define_module(&quot;Foo&quot;);&lt;/code&gt;. This will declare in Ruby a
module called &lt;code class=&quot;highlighter-rouge&quot;&gt;Foo&lt;/code&gt; that we can hang all of our C functions off.&lt;/p&gt;

&lt;p&gt;Then, we put our Ruby-ified &lt;code class=&quot;highlighter-rouge&quot;&gt;foo_rb_return_3&lt;/code&gt; in our module with
&lt;code class=&quot;highlighter-rouge&quot;&gt;rb_define_module_function(foo_rb_module_foo, &quot;return_3&quot;, foo_rb_return_3, 0)&lt;/code&gt;.
&lt;code class=&quot;highlighter-rouge&quot;&gt;rb_define_module_function&lt;/code&gt; is the underlying C function that is equivalent to
the &lt;code class=&quot;highlighter-rouge&quot;&gt;module_function&lt;/code&gt; method in Ruby. The first argument is module we want to
define that function on (in this case &lt;code class=&quot;highlighter-rouge&quot;&gt;Foo&lt;/code&gt;, which is &lt;code class=&quot;highlighter-rouge&quot;&gt;foo_rb_module_foo&lt;/code&gt; in C).
Then we give it a C string, which is the name of the function in Ruby
(&lt;code class=&quot;highlighter-rouge&quot;&gt;return_3&lt;/code&gt;), then the C function to call (&lt;code class=&quot;highlighter-rouge&quot;&gt;foo_rb_return_3&lt;/code&gt;) then the number of
positional arguments the function takes (in this case 0).Foo&lt;code class=&quot;highlighter-rouge&quot;&gt;, which is&lt;/code&gt;foo_rb_module_foo&lt;code class=&quot;highlighter-rouge&quot;&gt;in C). Then we give it a C string, which is the name of the function in Ruby (&lt;/code&gt;return_3&lt;code class=&quot;highlighter-rouge&quot;&gt;), then the C function to call (&lt;/code&gt;foo_rb_return_3`) then the number of
positional arguments the function takes (in this case 0).&lt;/p&gt;

&lt;h2 id=&quot;building-everything&quot;&gt;Building everything&lt;/h2&gt;

&lt;p&gt;Now that we’ve got our Rust and Ruby modules set up, we need to build
everything. Building the rust piece is easy, we can just run &lt;code class=&quot;highlighter-rouge&quot;&gt;cargo build&lt;/code&gt;.
That’ll create the &lt;code class=&quot;highlighter-rouge&quot;&gt;libfoo.a&lt;/code&gt; we referenced earlier.&lt;/p&gt;

&lt;p&gt;However, the Ruby-C-Rust bit is a little bit more involved. Linking C code
against the Ruby interpreter isn’t as easy as just calling &lt;code class=&quot;highlighter-rouge&quot;&gt;clang&lt;/code&gt; and expecting
everything to work. But fortunately, Ruby provides a convenient tool for us,
called “mkmf” (Makemakefile for long). To use it, we write a Ruby file called
&lt;code class=&quot;highlighter-rouge&quot;&gt;extconf.rb&lt;/code&gt; (it isn’t required to be called this, but this is the conventional
name for this file).&lt;/p&gt;

&lt;!--kg-card-begin: code--&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# extconf.rb&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;mkmf&quot;&lt;/span&gt;

&lt;span class=&quot;vg&quot;&gt;$LDFLAGS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot; -Ltarget/debug -lfoo &quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# preparation for compilation goes here&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;create_makefile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;foo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;!--kg-card-end: code--&gt;

&lt;p&gt;The only line of this file that is doing anything particularly interesting is
&lt;code class=&quot;highlighter-rouge&quot;&gt;$LDFLAGS &amp;lt;&amp;lt; &quot; -Ltarget/debug -lfoo &quot;&lt;/code&gt;. This line basically tells the Ruby
extension compiler where to find the Rust extension we created earlier.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;create_makefile(&quot;foo&quot;)&lt;/code&gt; creates a &lt;code class=&quot;highlighter-rouge&quot;&gt;Makefile&lt;/code&gt; that’ll compile all the C files in
the current directory, expecting to find an &lt;code class=&quot;highlighter-rouge&quot;&gt;Init_foo&lt;/code&gt; function. &lt;code class=&quot;highlighter-rouge&quot;&gt;Makefile&lt;/code&gt;s are
somewhat complex scripts for compiling C programs that have a varied set of
dependencies.&lt;/p&gt;

&lt;p&gt;Once that’s done we can run &lt;code class=&quot;highlighter-rouge&quot;&gt;make&lt;/code&gt;, and on my mac we’ll get an output file
called &lt;code class=&quot;highlighter-rouge&quot;&gt;foo.bundle&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;running-it&quot;&gt;Running it&lt;/h2&gt;

&lt;p&gt;So! Does it work? (Yes.)&lt;/p&gt;

&lt;p&gt;Here’s how you use it:&lt;/p&gt;

&lt;!--kg-card-begin: code--&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$: &amp;lt;&amp;lt; &quot;.&quot;
require &quot;foo.so&quot;

p(Foo.return_3)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;!--kg-card-end: code--&gt;

&lt;p&gt;We can require &lt;code class=&quot;highlighter-rouge&quot;&gt;foo.so&lt;/code&gt; and it’ll load the &lt;code class=&quot;highlighter-rouge&quot;&gt;foo.bundle&lt;/code&gt; because Ruby knows how
to translate between the various operating system dynamic library names.&lt;/p&gt;

&lt;p&gt;So, there you have it, a very simple C extension, in Ruby, without rubygems.&lt;/p&gt;</content><author><name>{&quot;twitter&quot;=&gt;&quot;penelope_zone&quot;}</name></author><summary type="html">For Rubyfmt I’m currently looking at rewriting significant sections in Rust, because there’s some performance issues. Broadly speaking, it turns out that cleaning up a very large Ruby parse tree (e.g. 4000 lines) can be slow because of the number of comparisons that have to be made. Rust can do this a lot faster.</summary></entry><entry><title type="html">Getting the most mileage out of Docker and Rails</title><link href="https://penelope.zone/2019/02/06/how-i-use-docker-with-rails-apps.html" rel="alternate" type="text/html" title="Getting the most mileage out of Docker and Rails" /><published>2019-02-06T13:59:54+00:00</published><updated>2019-02-06T13:59:54+00:00</updated><id>https://penelope.zone/2019/02/06/how-i-use-docker-with-rails-apps</id><content type="html" xml:base="https://penelope.zone/2019/02/06/how-i-use-docker-with-rails-apps.html">&lt;p&gt;Hi Folks,&lt;/p&gt;

&lt;p&gt;Recently I was working with a friend on their Rails app, which had been fully wrapped in a &lt;a href=&quot;https://docs.docker.com/compose/&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;docker-compose&lt;/code&gt;&lt;/a&gt; setup. They were quite rightly asking me questions about the best way to do things like run the server, run tests, migrate the database and other common Rails tasks. While I’ve seen a number of different ways of Dockerizing Rails in development, my preferred way is not to Dockerize my Rails app itself. In development I prefer to use Docker to manage any complex dependencies my application has, leaving my app running bare on my machine. When it comes to production time, that’s the ideal place to Dockerize your application. Let’s look at why!&lt;/p&gt;

&lt;h2 id=&quot;it-starts-with-the-rails-way&quot;&gt;It starts with the “Rails Way”&lt;/h2&gt;

&lt;p&gt;The “Rails Way” is all the stuff that Rails is designed to make really easy, for example:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Using generators to quickly build out standard pieces of your app&lt;/li&gt;
  &lt;li&gt;The Rails console to quickly modify development data&lt;/li&gt;
  &lt;li&gt;Code reloading&lt;/li&gt;
  &lt;li&gt;Being able to get in to your database if you really need to&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In order to do get all the benefits of Rails’s finely honed development tools you typically need a postgres (or mysql) database, and a redis instance (because you’re using &lt;a href=&quot;https://github.com/mperham/sidekiq&quot;&gt;sidekiq&lt;/a&gt; right ;)). Those dependencies are all pretty easy to get going on a Mac or Linux machine these days. So: if I’m building a Rails app that has an eventual Docker target in production, but only those simple dependencies, it is my preference to not use Docker in development &lt;em&gt;at all&lt;/em&gt;. This way, I get the experience of developing Rails as it is intended, and all the benefits that come with it being local to my machine.&lt;/p&gt;

&lt;p&gt;I have my editor set up so that I can drop in to a Rails console or execute the tests with a quick flick of my hand. Those shortcuts work because the commands execute on the local machine. I’ve never found a way where I can achieve the same level of seamlessness using any combination of Docker or &lt;code class=&quot;highlighter-rouge&quot;&gt;docker-compose&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;but-what-about-if-my-rails-app-needs-a-constellation-of-microservices-to-be-realistic&quot;&gt;But what about if my Rails app needs a constellation of microservices to be realistic&lt;/h2&gt;

&lt;p&gt;This is becoming a more common case. Let’s say that you’re a company that grew up on a Rails monolith. You’ve extracted functionality to a microservice that means you can’t realistically develop your Rails app without the extracted microservice up and running. Also, your microservices are a huge pain to coordinate without Docker and &lt;code class=&quot;highlighter-rouge&quot;&gt;docker-compose&lt;/code&gt;. You also have this case if you have a more complex dependency like Elasticsearch, or Neo4j, or some other component to your application that isn’t trivial to &lt;code class=&quot;highlighter-rouge&quot;&gt;brew install&lt;/code&gt; and have work.&lt;/p&gt;

&lt;p&gt;So your Rails app is dependent on something that you can’t for whatever reason run cleanly bare on your machine. What I do in these cases is build a &lt;code class=&quot;highlighter-rouge&quot;&gt;docker-compose.yml&lt;/code&gt; file which knows how to spin up all my app’s dependencies, and then use &lt;a href=&quot;https://github.com/bkeepers/dotenv&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;.env&lt;/code&gt;&lt;/a&gt; to point my development server running on my bare machine at those services. This way, I get all the benefits of local Rails development, and all the benefits of Docker for the things that are hard to run on my machine.&lt;/p&gt;

&lt;h2 id=&quot;i-love-using-docker-for-rails-in-production&quot;&gt;I love using Docker for Rails in production&lt;/h2&gt;

&lt;p&gt;For clarity, I &lt;em&gt;do&lt;/em&gt; think you should still Dockerize your Rails app if you have a good production container runtime story. Containers provide you with the ability to deploy a single static artifact of your application. This artifact ensures that every server is running the exact same code, has the exact same assets, and if configured properly, is talking to the exact same dependencies. There’s a mountain of benefit there. In production, I don’t need many of those “Rails Way” things, a console, a reloader, running the tests are all not useful in that environment. It’s quick and easy to get started with Docker for Rails. It’s a very appropriate way to get your app to production.&lt;/p&gt;

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

&lt;p&gt;Working with Rails for the last 10 years of my life has been an absolute joy. I want to keep using the amazing tooling that I’m familiar with. I want to get as much of the benefit as I can from Docker, and all the tooling that comes with it. In my opinion, though, Docker isn’t well suited for Rails development because the local development experience has been so thoroughly optimized. Instead: using Docker for what it’s good at which is isolating dependencies makes a tonne of sense in a traditional Rails development context. Docker is well suited to deploying Rails apps to production, however, and you should by no means take this as a dislike for the technology. Docker is great, and using it in production has genuinely made my life significantly easier. Your optimised development environment is Rails, with docker supporting, and not the other way around.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/penelopezone&quot;&gt;If you liked this post, please consider following me on twitter&lt;/a&gt;&lt;/p&gt;</content><author><name>{&quot;twitter&quot;=&gt;&quot;penelope_zone&quot;}</name></author><summary type="html">Hi Folks,</summary></entry><entry><title type="html">Questions for a prospective employer about on call (2/3)</title><link href="https://penelope.zone/2019/01/14/questions-for-a-prospective-employer-about-on-call-2-3.html" rel="alternate" type="text/html" title="Questions for a prospective employer about on call (2/3)" /><published>2019-01-14T13:10:42+00:00</published><updated>2019-01-14T13:10:42+00:00</updated><id>https://penelope.zone/2019/01/14/questions-for-a-prospective-employer-about-on-call-2-3</id><content type="html" xml:base="https://penelope.zone/2019/01/14/questions-for-a-prospective-employer-about-on-call-2-3.html">&lt;p&gt;Hi Folks,&lt;/p&gt;

&lt;p&gt;This is part two in my series about talking to prospective employers about on call. In &lt;a href=&quot;https://penelopezone.com/questions-for-a-prospective-employer-about-on-call-1-3/&quot;&gt;the first part&lt;/a&gt; we covered a bunch of general questions. In this part, we’ll dig down in to specific questions about incidents and how they function. An incident is something that happens that causes you to get paged when you’re on call, and so asking questions around this is pretty important.&lt;/p&gt;

&lt;h2 id=&quot;specific-questions-related-to-incidents&quot;&gt;Specific questions related to incidents&lt;/h2&gt;

&lt;h3 id=&quot;how-many-people-are-on-the-smallest-team-that-is-on-call-how-frequently-do-they-paged-for-out-of-hours-incidents-are-you-doing-anything-to-help-alleviate-their-pain&quot;&gt;How many people are on the smallest team that is on call, how frequently do they paged for out of hours incidents? Are you doing anything to help alleviate their pain?&lt;/h3&gt;

&lt;p&gt;By definition the smallest on-call team has their engineers rotate most frequently. If you get an answer which is a really small number (say 2 people in an engineering org of 50) that’s a big problem. Unless the platform that you’re working on is ridiculously stable, you’re going to have a bad time. Really this question is aimed to help you get an understanding of how the engineering leadership in the business thinks about the health of their incident management program. Are they working to remove single points of failure? Are they working to support that small team by sharing on-call with another team? Are they rotating engineers or cross training people back in? These are all good questions to ask to get a feeling for how much pain the worst off engineers in the company are. More importantly if you were to end up in the same situation, how likely it is that you’d have a leader you could talk to to make sure something is done about it.&lt;/p&gt;

&lt;h3 id=&quot;does-your-company-have-distributed-employees-that-can-take-on-call-for-times-that-make-sense-for-them&quot;&gt;Does your company have distributed employees that can take on call for times that make sense for them?&lt;/h3&gt;

&lt;p&gt;I was once lucky enough to work on an on-call team that split between East Coast America and European time zones. The five/six hour time shift meant that we as a group could take some of each other’s on-call burden. We’d specifically level it in such a way that the most obnoxious times for people to receive a page were covered by a more reasonable time in the other time zone. This gets easier as you have wider distribution.&lt;/p&gt;

&lt;p&gt;Many companies do not have the luxury of doing this, because everyone works in a single time zone in a single office. If you do have a distributed employee base taking advantage of that in order to alleviate some of the pages at the worst hours can be really great. Talk to individual engineers and individual engineering managers about how they deal with remotes and timezones.&lt;/p&gt;

&lt;h3 id=&quot;do-teams-routinely-create-and-put-in-to-place-newly-automated-alerts&quot;&gt;Do teams routinely create and put in to place newly automated alerts?&lt;/h3&gt;

&lt;p&gt;This is more common as a practice than it was, say, five years ago. Automated alerts are most important around new services or new features that are going into production. It sort of maps back into the &lt;a href=&quot;https://penelopezone.com/questions-for-a-prospective-employer-about-on-call-1-3/#doyouhaveaseverityscaleifsocouldyouwalkmethroughwhattheratingsareatwhatseveritypeoplecanbecalledoutofhourswhomakesseveritydeterminationsetc&quot;&gt;severity scale&lt;/a&gt; discussion. Are you defining your severity scale by something automated, or relying on some kind of human at your back?&lt;/p&gt;

&lt;p&gt;One of the things this question is designed to hint at though is which tooling a company is using to get these alerts in place. Do they have something like &lt;a href=&quot;https://www.datadoghq.com/&quot;&gt;Datadog&lt;/a&gt; integrated all the way to their Pagerduty? Are they using the &lt;a href=&quot;https://www.cncf.io/&quot;&gt;CNCF&lt;/a&gt; &lt;a href=&quot;https://prometheus.io/&quot;&gt;Prometheus&lt;/a&gt;/&lt;a href=&quot;https://grafana.com/&quot;&gt;Grafana&lt;/a&gt;/&lt;a href=&quot;https://www.datadoghq.com/&quot;&gt;AlertManager&lt;/a&gt; stack? How easy is it for an engineer to synthesize a hypothesis about what a good alert is, test it, and then put it into production if the alert is meaningful? Organizations that don’t have a good strategy around automated alerting are generally resistant to adding newly automated alerts, and this is what we’re trying to bare out here. How much work is it for you as an engineer to add a new alert in production?&lt;/p&gt;

&lt;h3 id=&quot;do-you-conduct-any-kind-of-review-on-your-automated-alerts-to-ensure-they-are-not-becoming-noisy&quot;&gt;Do you conduct any kind of review on your automated alerts to ensure they are not becoming noisy?&lt;/h3&gt;

&lt;p&gt;Businesses grow over time, operational characteristics of our systems change, third-party providers change their service levels. The metrics against which a given alert fires are going to drift over time. An alert that was very indicative of a problem six months ago might suddenly become noisy because of this drift. An alert which used to be sensitive and accurate may fail to fire when data starts to change.&lt;/p&gt;

&lt;p&gt;Conducting some kind of alert review on a regular cadence is a great way to prevent this. Validate that the alert thresholds are still tight, that we’re not too close to suddenly firing and waking somebody up at 4am when we didn’t need to. If your teams have a reasonable workload this entire exercise can consume less than an hour a month, and that’s totally worth it.&lt;/p&gt;

&lt;p&gt;This is one of those questions where if you get a “no” answer, it might not be a problem. The business might not be changing fast enough to require this kind of review. There may be mitigating circumstances. Here you’re looking, again, for thoughtful leadership responses and or good mitigations in place, not just a flat out “this is not a problem for us” with no reasoning.&lt;/p&gt;

&lt;h3 id=&quot;do-you-have-a-supportoperationscustomer-success-team-that-can-call-a-page-in-lieu-of-an-automated-alert&quot;&gt;Do you have a support/operations/customer success team that can call a page in lieu of an automated alert?&lt;/h3&gt;

&lt;p&gt;If something’s going horribly wrong, you want to be notified. Sometimes you’ve failed to cover your service in enough observability, something gets missed, and you’re down and not automatically woken up. Hopefully, you’ve got a support team who is awake to notice. Hopefully, they’ve got a path to escalate to you.&lt;/p&gt;

&lt;p&gt;This can be a double-edged sword. A human making the decision to file a JIRA versus waking you up in the middle of the night can be a fraught thing. They don’t want to be a jerk for waking you up, and you don’t want to be woken up. Similarly, they’re incentivized to keep the customers happy, and so filing a ticket and waiting until morning might be a really shitty thing for them to have to deal with on their end. This is where having a severity scale can help, but when it comes down to human determination, there’s always going to be room for some error. The important thing for you as the engineer to know is that if they do wake you up for something that isn’t as big of a deal as it seems at first, that’s a systemic failure, it’s not the fault of that person. You need to collaborate with them to clarify on either the severity scale, how to triage incidents, or how the system works.&lt;/p&gt;

&lt;p&gt;You’re going to get a lot of varied answers to this question because every organization puts these teams together differently, and gives those teams different objectives. This is a good opportunity for you to dig into the structure of the company that you’re joining such that it exists beyond the engineering organization. Engineering doesn’t exist in a vacuum, and so when you’re thinking about this, understand how communication from the company’s customers makes its way to engineers. When something is broken for a customer, what exactly happens before an engineer gets involved, and how frequently do humans make a call to bring an engineer in out of hours?&lt;/p&gt;

&lt;h3 id=&quot;do-you-have-any-kind-of-24-by-7-team-eg-a-noc-soc-or-cloud-operations-team-that-does-first-level-triage-on-behalf-of-engineers&quot;&gt;Do you have any kind of 24 by 7 team (e.g. a NOC, SOC, or “cloud operations” team) that does first level triage on behalf of engineers?&lt;/h3&gt;

&lt;p&gt;A yes answer to this question will make your life significantly easier. To take a quick diversion for a second: at DigitalOcean there is a 24x7 operations team called CloudOps (short for cloud operations) that works in three shifts. They’re technical folks who mix engineering, sysadmin, and SRE skills. They exist as a point to which support teams can escalate issues, make severity determinations if engineers aren’t already on top of a problem. They coordinate the start of an incident to get everyone needed to resolve it. This team is great (I love you if you’re reading this CloudOps) and it was one of the best tools in my operational arsenal. They would frequently prevent something from getting through to my team by executing a playbook against an incident for us, and for that, I’m eternally grateful.&lt;/p&gt;

&lt;p&gt;Many engineering organizations are too small to have a team like this. If you’re big and you don’t have a team like this it might be worth considering what the impact of a 24 hour operations team would be. In my experience having a series of operators and communicators who are continually fresh can significantly reduce the time to resolution on any incident.&lt;/p&gt;

&lt;p&gt;Getting a “no” answer to a question like this is pretty standard, and it’s not really a red flag. In addition to the usual 24x7 support and success operation that many organizations have, having a 24x7 technical team as well can be unnecessary overkill. If you don’t have a team like this, though, it might be worth considering you could form a rotation of this form. If your business has a significant operational burden (not everyone is a cloud hosting provider, or of similar class), it really can be a lifesaver.&lt;/p&gt;

&lt;h3 id=&quot;have-you-ever-had-an-incident-where-you-felt-like-a-severity-decision-was-made-for-an-incident-that-was-too-high-causing-people-to-get-paged-when-they-shouldnt-have-how-did-you-remediate-that&quot;&gt;Have you ever had an incident where you felt like a severity decision was made for an incident that was too high, causing people to get paged when they shouldn’t have? How did you remediate that?&lt;/h3&gt;

&lt;p&gt;This is one that I’d aim squarely at the engineering leadership of a company. Keeping incidents appropriately sev’d is going to show a strong difference between a healthy and unhealthy engineering organisation. When everything’s a SEV-0 biggest most important fire in the universe nothing is. It’s a natural response though: any little defect in the product is probably a big deal to somebody. Most likely your customer-facing teams are going to take some flak for even the smallest of bugs and it’s natural to want to fix them as quickly as possible.&lt;/p&gt;

&lt;p&gt;Conversely: engineers getting paged too frequently causes them to burn out and leave, so striking a balance is important. When a call for severity is made it is of course open to inspection and review. If any person genuinely feels like an incident was over or under sev’d, they should absolutely speak up about it. It’s then up to the leadership of the company, or someone who’s responsible for running the incident management program to make a decision as to how that call ultimately sits.&lt;/p&gt;

&lt;p&gt;Usually, when a “bad” call of this form is made, it’s due to a lack of communication. What that means is that probably some documentation needs updating, how a product works needs to be clarified, or the engineering team needs to improve their automated alerting or metrics gathering such that it’s more obvious what’s going wrong when something’s going wrong.&lt;/p&gt;

&lt;p&gt;You may find that this hasn’t happened, because it’s not humans that are dealing with alerts, but in general, making sure that someone’s got an eye on this is a good idea.&lt;/p&gt;

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

&lt;p&gt;Incidents are painful for everyone involved. When they trigger, who triggers them, and what happens when they trigger are really important for you to understand. Healthy engineering organizations have a strategy around alerts that goes beyond “customers start complaining and then we respond”. Digging in to the alerting strategy, alerting review, and process for support escalations will help you get a better handle on whether or not a company is careful and considered about its on call.&lt;/p&gt;</content><author><name>{&quot;twitter&quot;=&gt;&quot;penelope_zone&quot;}</name></author><summary type="html">Hi Folks,</summary></entry><entry><title type="html">Questions for a prospective employer about on call (1/3)</title><link href="https://penelope.zone/2019/01/04/questions-for-a-prospective-employer-about-on-call-1-3.html" rel="alternate" type="text/html" title="Questions for a prospective employer about on call (1/3)" /><published>2019-01-04T14:45:23+00:00</published><updated>2019-01-04T14:45:23+00:00</updated><id>https://penelope.zone/2019/01/04/questions-for-a-prospective-employer-about-on-call-1-3</id><content type="html" xml:base="https://penelope.zone/2019/01/04/questions-for-a-prospective-employer-about-on-call-1-3.html">&lt;p&gt;Hi Folks,&lt;/p&gt;

&lt;p&gt;This is the first in a series of three blog posts. These contain questions that I asked prospective employers when I was interviewing recently and why I asked them. On-call is one of the biggest determiners in whether or not a job is particularly painful. It also seems to me to be becoming a more “normalized” practice. These questions are designed to give you a feel for how seriously engineers, and, importantly, engineering leadership take their on-call responsibilities.&lt;/p&gt;

&lt;p&gt;The reason you want to determine how engineering leaders think about on-call is that they’re ultimately responsible for how well or badly on-call will go. Things like how much engineering pain they’re aware of, how they’re helping drowning teams, and what they personally do to ensure there is mature operational practice have an outsized impact on how on-call goes.&lt;/p&gt;

&lt;p&gt;In this first part, I’ll address questions that have to do with what I’m calling “general maturity”. This is a quick health check on where an organization is at on the design of their on-call practice. Do they have good procedures, are they thinking about who’s on-call and when, do they have an understanding of the uptime requirements of their product?&lt;/p&gt;

&lt;p&gt;In the next post, I’ll talk about the specific nitty-gritty of being on-call. In the final one, what the entire incident management program of a company looks like, not just the on-call part.&lt;/p&gt;

&lt;p&gt;These questions are formed from serving close to three years as an on-call engineer at organizations of various sizes. Also serving as an engineering manager for the last year of a team of 3, all of whom were on-call. I’m by no means trying to declare this is the absolute best framework to assess a company by, but it will let you start discussions and have a lot of insight. I really do hope you enjoy it.&lt;/p&gt;

&lt;h2 id=&quot;general-maturity-questions&quot;&gt;General maturity questions&lt;/h2&gt;

&lt;h3 id=&quot;does-product-have-to-be-online-247-do-you-expect-engineers-to-be-on-call-out-of-hours&quot;&gt;Does $product have to be online 24/7? Do you expect engineers to be on-call out of hours&lt;/h3&gt;

&lt;p&gt;This may seem like a “dumb” question, but I’ve been surprised by companies that have answered no to this question. There are obvious places where the answer to this question is no: retail POS, many types of financial services businesses, etc. If you get a “no” answer to this question, and it doesn’t sit right with you: probe. You might find that this isn’t well considered and that the software, in fact, needs to be online 24 hours. If that’s the case that’s a big red flag.&lt;/p&gt;

&lt;p&gt;You’ll often hear a “yes” answer as a simple default. Things like clouds, software that people might need to query information out of at any time of day, communications software, etc, it’s probably a well-founded reason. If you get a “yes” answer and you think that the product doesn’t need to be online 24/7, again, probe. Making sure that you get to a good reason for the availability expectations that the leadership of a company is placing on you is important. A 24/7 bound is basically the starting point for all of the questions in the rest of this post. Pages during “normal business hours” or slightly outside (say 7 am to 7 pm) are significantly less painful to deal with than those in the middle of the night (put your hands up 4 am ops club). If you’re entering into an organisation that expects its engineers to be on-call out hours, you want to know that.&lt;/p&gt;

&lt;p&gt;You want to inquire here for uncertainty or bad reasons for uptime requirements. If you’re expected to do on-call for something that demonstrably has almost no users in the wee hours, that’s a problem. Waking up at 4am sucks, and you want to make sure it’s for good reasons, so this is really the start of the conversation, and your chance to probe both individual contributor engineers and engineering leadership (I’ve asked this question all the way up to CTO level) about how they think about on-call.&lt;/p&gt;

&lt;h3 id=&quot;is-anyone-at-this-company-performance-managed-on-the-reliability-of-the-software-that-is-being-produced&quot;&gt;Is anyone at this company performance managed on the reliability of the software that is being produced?&lt;/h3&gt;

&lt;p&gt;No is the most common answer to this question. Most companies are small and require little process. As such, frequently, shipping features is performance managed and reliability often isn’t. If you’re joining a company that’s lucky enough to have a “real” SRE (Site Reliability Engineering) function (not a team of SREs that sit somewhere, but SREs embedded within product teams) the answer might be someone in SRE leadership. Sometimes a VP of engineering or Director will take on this role, and try to manage reliability holistically. That sometimes works, and sometimes doesn’t.&lt;/p&gt;

&lt;p&gt;You should ask this question more as a determiner of attitude than a binary yes/no question on which to eliminate a company. If engineering managers and engineering leadership want to improve in this area, that’s a great signal. If it’s something to which they’re not putting a large degree of concern, that can be a red flag.&lt;/p&gt;

&lt;p&gt;If you hear words or explanations to the effect of “we trust individual engineers to manage the reliability of the software that they write”, that’s a problem. No matter how well-intentioned an engineer is if the structure of their organization is focused on shipping software that engineer will eventually tune out their focus on reliability. Non-functional requirements, things like metrics, timeouts, retries, etc will go to the wind as you naturally incentivize those engineers to head down the “easy” path and write code that “just” works, apart from the myriad failure conditions they didn’t account for.&lt;/p&gt;

&lt;h3 id=&quot;is-there-any-kind-of-cross-organisational-service-level-management-that-all-teams-aim-for-eg-support-engineering-on-successful-ticket-submissions-per-hour-checkouts-team-on-checkouts-per-hour-etc-if-so-when-teams-miss-their-prescribed-service-level-objectives-what-do-you-do&quot;&gt;Is there any kind of cross organisational service level management that all teams aim for (e.g. support engineering on successful ticket submissions per hour, checkouts team on checkouts per hour etc). If so, when teams miss their prescribed service level objectives, what do you do?&lt;/h3&gt;

&lt;p&gt;This question is a good follow up to the previous one. Generally speaking, if nobody is being performance managed on service level, then service level won’t be being measured either. If service level is being managed, this is a great place to probe into what that practice looks like. Are they measuring business metrics (tickets submitted, emails sent, etc), or non-functional metrics (throughput, latency, error rate)? If so, does the organisation have a preference on service level of one kind of metric over the other? Neither is necessarily better but in my experience organizations that really care about their users tend to focus on the functional metrics.&lt;/p&gt;

&lt;p&gt;Asking what organizations do if teams miss their prescribed service level is designed to probe at how the company holistically treats the health of their systems. Some companies will respond to failing service levels by making teams do reliability work until they are back within that service level. Some will take a look at any open postmortem action items and push those to the to top of their priority list. They’ll do this to improve their service level rather than continuing to ship features. Some will do nothing at all but insist that they really do care about reliability.&lt;/p&gt;

&lt;p&gt;Use this as a good place to determine if reliability is being measured in any kind of consistent way throughout the organisation, or that it’s up to individual teams and engineers that care. When you’ve got a consistent organisational focus on reliability, that’s a sign that on-call is less likely to be hell.&lt;/p&gt;

&lt;h3 id=&quot;how-do-teams-at-your-company-manage-their-on-call-rotation&quot;&gt;How do teams at your company manage their on-call rotation?&lt;/h3&gt;

&lt;p&gt;The most likely answer that you will get to this question is that “we leave it to individual teams to manage their on-call rotations”. That’s a good answer but has a couple of pitfalls. If there’s no holistic review or individual teams within the organisation don’t have strong managers or a strong retrospective process, it’s easy for those teams to get stuck with a static on-call rotation. Being stuck like this makes people less adaptable to changes in circumstance, and can be a red flag.&lt;/p&gt;

&lt;p&gt;By far and away the most common rotation I’ve seen is that teams do “on-call primary for 24 hours a day, for a week, and then rotate”, sometimes referred to as a 24 by 7. There’s usually some kind of secondary rotation which is a person who is the backup if the first person fails to respond. Sometimes that person is the lead of the team. As a final step: some teams opt to page everyone on the team if the first page is not responded to. This kind of rotation won’t work for everyone, and it’s important to make sure that a rotation of that form isn’t a blindly followed default. Look to see if the on-call rotation has actually been well considered when interviewing for a team. This is a great question to put to an individual engineering manager. As you go higher into engineering leadership, specific rotation details tend to melt away.&lt;/p&gt;

&lt;p&gt;Another line of questioning here is how a team deals with swaps. Emergencies, flights, conferences, and vacations all happen. Determining if the team’s culture is healthy enough to support these kinds of things without scorekeeping can give you a really good lens into how healthy that team is.&lt;/p&gt;

&lt;p&gt;A spin on this question for engineering leadership is to see what kind of health checks they’re conducting on their team’s rotations. Do they get any kind of reporting as to who’s getting paged the most frequently in their organisation? Do they insist that managers rotate an individual when that individual gets paged too many times in a week? What kind of high-level on-call rotation reviews are being conducted?&lt;/p&gt;

&lt;p&gt;I’ll also note here that some people absolutely cannot deal with an out of hours call. This is for a variety of reasons ranging from being a single parent to mental health issues, and so on.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Sure. My problem is when that’s assumed to be enough flexibility for everyone.&lt;/p&gt;

  &lt;p&gt;I’m a single parent. My kids school still starts at 8 regardless of whether I was up the night before. There’s nobody else to take him. Getting up after midnight just is not an option.&lt;/p&gt;

  &lt;p&gt;— Sarah Mei (@sarahmei) &lt;a href=&quot;https://twitter.com/sarahmei/status/1078536116658089984?ref_src=twsrc%5Etfw&quot;&gt;December 28, 2018&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;p&gt;These people also might be fantastic engineers, and excellent on-call responders, who don’t mind the interruptive work during their day to day. If you can determine that they’ve got some kind of process for dealing with this, or do 12 hours on-call slots where some people volunteer to take overnights on behalf of their team, that can also work. The point is, you should probe to determine if there’s any kind of flexibility there. Even if you don’t need it now, you may in the future, and it’s good to know it’s available.&lt;/p&gt;

&lt;p&gt;Every answer that you hear to this question will be different. Red flags will include that someone in leadership can’t tell you holistically how different teams manage different on-calls. Also look to see if on-call is dictated across the entire organisation with little to no team specific flexibility. If a mid-level engineering manager has their on-call rotation all laid out but doesn’t have a specific reason as to why the on-call is like that, it might be worth probing to see if they’re open to changing it based on discussions and retros with the team.&lt;/p&gt;

&lt;h3 id=&quot;do-you-have-a-severity-scale-if-so-could-you-walk-me-through-what-the-ratings-are-at-what-severity-people-can-be-called-out-of-hours-who-makes-severity-determinations-etc&quot;&gt;Do you have a “Severity Scale”? If so, could you walk me through what the ratings are, at what severity people can be called out of hours, who makes severity determinations, etc?&lt;/h3&gt;

&lt;p&gt;This is a meaty question, and will likely consume the majority of the conversation with someone who’s in engineering leadership. There’s a lot of data that you can take away from this one. Firstly, you should aim to get the description of what the severity levels are. For example, you might have:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;SEV-0: A critical business-ending event, multiple products are unavailable, all customers cannot log in, registrations are failing, the whole site is unavailable, etc. Engineers and engineering leadership paged immediately to coordinate response&lt;/li&gt;
  &lt;li&gt;SEV-1: A serious impact to a single product area, business function, etc. Entire site responding but outside of usual performance SLO, Product is regionally unavailable in a single country/area of the world. Engineers paged, potentially an engineering leader paged to coordinate incident response if needed&lt;/li&gt;
  &lt;li&gt;SEV-2: A serious workflow breaking bug in a single product that does not have a workaround, single view or part of site outside of performance SLO. Engineers paged immediately&lt;/li&gt;
  &lt;li&gt;SEV-3: A workflow breaking bug exists but support has been able to determine a workaround, JIRA ticket filed and engineers expected to fix when they come in the next day&lt;/li&gt;
  &lt;li&gt;SEV-4: minor bug or piece of functionality not working, either not serious enough to need a workaround or simple workaround exists, JIRA filed, engineers expected to fix as part of usual bug fixing/sprint work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You’re looking for something that is precise. Ideally you will have specific definitions based on the product and business units within the company that you’re interviewing for. The reason that you want something like this is that it clearly distinguishes when you can be interrupted out of hours to fix problems. Having shared definitions like this enables you, your engineering leadership, and your support and operations folks to agree on how to respond to any given problem that they’re seeing.&lt;/p&gt;

&lt;p&gt;As to who makes severity decisions: you’ll want the majority of incidents to be triggered automatically. It’s worth acknowledging, however, that we can’t cover all possible things that would go wrong in automated alerts. As such we usually concede that as a last resort a human is going to make a call to bring in engineers to try and fix the problem. If that’s the case, you’ll want to follow up by probing into who can make severity decisions, and out of hours page decisions. When a decision to page someone is made who makes that decision: a support individual contributor? Support manager? Is there an operations team that can triage for you? An on-call incident manager who is an engineer from any team? Those things will determine how frequently you get a bad page and have to down-sev or redirect an incident.&lt;/p&gt;

&lt;p&gt;It’s worth noting here that not having a sev scale isn’t necessarily a bad thing. If you’re joining a tiny company (n &amp;lt; 15 engineers on staff) you might not have a wide enough range of things that can go wrong as to need this much process and documentation. It’s worth considering whether the answers that you hear map to the amount of process you’d expect the company at which you’re interviewing to have.&lt;/p&gt;

&lt;p&gt;A big red flag here is that if this document exists, but is stale, isn’t collaborated on by all stakeholders, etc. It should be a living document that accounts for new products, launches, teams, etc. Not a static document that was dictated by some engineering leader one time and then never changed again.&lt;/p&gt;

&lt;h3 id=&quot;is-there-anything-similar-to-a-holistic-incident-management-program-at-this-company-is-someone-in-charge-of-that&quot;&gt;Is there anything similar to a holistic incident management program at this company? Is someone in charge of that?&lt;/h3&gt;

&lt;p&gt;This question goes right along with the severity scale question. Answers that you’re looking for here include maintaining the severity scale, postmortem process (if they have one!), pre- and post-incident management, etc. Not everyone has this! Larger companies that care about reliability tend to hire either a technical program manager into this position or make it the responsibility of one of the more senior engineers on staff.&lt;/p&gt;

&lt;p&gt;Hearing a “no” here, again, isn’t a hard elimination. Not every company needs something like this, not every company has a service level requirement on their software that requires this role. If the program does exist, digging into why it was set up, and digging into why the person who is running it is running it can be a really good indicator of a healthy and mature attitude towards on-call.&lt;/p&gt;

&lt;h3 id=&quot;generally-speaking-is-the-number-of-incidents-that-engineers-are-dealing-with-out-of-hours-going-up-or-down&quot;&gt;Generally speaking, is the number of incidents that engineers are dealing with out of hours going up or down?&lt;/h3&gt;

&lt;p&gt;This is really the start of a discussion. Based on the answer that you hear you’ll want to ask what specific steps are being taken to improve the situation, what new practises the organisation is using, etc. Are your engineering leaders concerned with the state of this at all? Do they know? What are they doing to personally improve the lives of the engineers on the ground? Are those engineering leaders feeling any of the pain? Use this one as a point to establish whether or not you’re likely to encounter increasing or decreasing pain. I’ve not got a whole lot more to say here, because repeatedly asking “why?” at this stage is basically the best way to go.&lt;/p&gt;

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

&lt;p&gt;This first round of questions will give you some insight in to the maturity of a specific organization’s on-call practise. If you hear strong consistent answers that have been clearly thought about through all these questions, that’s a really good sign. If you come away from the discussion worried, that’s something to follow up in with further conversations. I’ve found that when people are on top of on-call, you can bare it out really quickly. I do hope this is useful for you and helps you start to build a framework about what a good on call practice might look like for you.&lt;/p&gt;</content><author><name>{&quot;twitter&quot;=&gt;&quot;penelope_zone&quot;}</name></author><summary type="html">Hi Folks,</summary></entry><entry><title type="html">How I organise my VIM hotkeys</title><link href="https://penelope.zone/2018/12/27/how-i-organise-my-vim-hotkeys.html" rel="alternate" type="text/html" title="How I organise my VIM hotkeys" /><published>2018-12-27T10:03:35+00:00</published><updated>2018-12-27T10:03:35+00:00</updated><id>https://penelope.zone/2018/12/27/how-i-organise-my-vim-hotkeys</id><content type="html" xml:base="https://penelope.zone/2018/12/27/how-i-organise-my-vim-hotkeys.html">&lt;p&gt;Intermediate to advanced VIM users love to extract common workflows to hotkeys. You might want to optimise workflows like running tests, adding files to git/doing a commit, or reformatting text. The thing is, as you add more and more workflows, organising these hotkeys can become a nightmare. For the past several years, I’ve had a philosophy to organising mine that has really helped me.&lt;/p&gt;

&lt;h2 id=&quot;the-leader-key&quot;&gt;The leader key&lt;/h2&gt;

&lt;p&gt;For me it all starts with the leader key, &lt;code class=&quot;highlighter-rouge&quot;&gt;\&lt;/code&gt; by default, but some people use &lt;code class=&quot;highlighter-rouge&quot;&gt;,&lt;/code&gt;. In a VIM setup that isn’t at all customised, no hotkeys follow the leader key, and this makes it an excellent place to hang functionality from. In my &lt;code class=&quot;highlighter-rouge&quot;&gt;.vimrc&lt;/code&gt; there’s a whole section filled with lines that look like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;map &amp;lt;leader&amp;gt;jna :!nosetests &amp;lt;CR&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This says “when I press &lt;code class=&quot;highlighter-rouge&quot;&gt;\jna&lt;/code&gt; run the shell command &lt;code class=&quot;highlighter-rouge&quot;&gt;nosetests&lt;/code&gt;”.&lt;/p&gt;

&lt;p&gt;The first protip I have for you is fairly simple: hanging everything off the leader key is a great place to start your hotkeying.&lt;/p&gt;

&lt;h2 id=&quot;prefix-trees&quot;&gt;Prefix trees&lt;/h2&gt;

&lt;p&gt;Consider a world in which I had my leaders set up like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;map &amp;lt;leader&amp;gt;j :!bundle exec rspec&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;jf :!bundle exec rspec %&amp;lt;CR&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This creates an ambiguity, if you press &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;leader&amp;gt;j&lt;/code&gt;, VIM can’t know whether or not you want to execute the first or second command: until you press the &lt;code class=&quot;highlighter-rouge&quot;&gt;f&lt;/code&gt; key, or wait a for some period of time. This creates an unnatural pause if you do want to run the &lt;code class=&quot;highlighter-rouge&quot;&gt;j&lt;/code&gt; leader, which breaks flow. Additionally, if you press &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;leader&amp;gt;j&lt;/code&gt; and then pause for a second because you are interrupted for any reason, you’re going to run &lt;code class=&quot;highlighter-rouge&quot;&gt;bundle exec rspec&lt;/code&gt; executing your entire test suite, instead of executing a command over a single file (the % character passes the current filename to the command, which RSpec will then execute as a single file test, rather than all of them).&lt;/p&gt;

&lt;p&gt;This problem is because one leader &lt;code class=&quot;highlighter-rouge&quot;&gt;j&lt;/code&gt; is a valid prefix of &lt;code class=&quot;highlighter-rouge&quot;&gt;jf&lt;/code&gt;. The way to fix this is to use a “prefix tree”, where there are no valid commands which overlap in their pefixing. Rather every command is valid and distinct, causing you to type an entire sequence before anything will execute. In my dotfiles, I have all of my leader sequences mapped such that they form a prefix tree, have a &lt;a href=&quot;https://github.com/penelopezone/dotfiles/blob/master/vim/vimrc.symlink#L117-L170&quot;&gt;look&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;map &amp;lt;leader&amp;gt;jca :!bundle exec cucumber --no-color&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;jra :call RunAllSpecs()&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;jrf :call RunCurrentSpecFile()&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;jrn :call RunNearestSpec()&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;jrl :call RunLastSpec()&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;jr! :call RunLastFailure()&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;jna :!nosetests &amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;jnf :!nosetests %&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;jma :!ruby test/test_helper.rb &amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;jmf :!bundle exec ruby % &amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;jta :!./script/test&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;jmf :!ruby %&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;rpf :!python3 % &amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;rrf :!bundle exec ruby %&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;rb :!bash &amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;rv :so ~/.vimrc &amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;rm :!touch % &amp;amp;&amp;amp; make &amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;rc :!ctags -R&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;cr :!cargo run&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;cb :!bash -c 'cargo build 2&amp;gt;&amp;amp;1 \| head -n 10'&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;ct :!cargo test&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;eir o&amp;lt;ESC&amp;gt;ogem &quot;rspec-core&quot;, :github =&amp;gt; &quot;rspec/rspec-core&quot;&amp;lt;CR&amp;gt;gem &quot;rspec-expectations&quot;, :github =&amp;gt; &quot;rspec/rspec-expectations&quot;&amp;lt;CR&amp;gt;gem &quot;rspec-mocks&quot;, :github =&amp;gt; &quot;rspec/rspec-mocks&quot;&amp;lt;CR&amp;gt;gem &quot;rspec-support&quot;, :github =&amp;gt; &quot;rspec/rspec-support&quot;&amp;lt;CR&amp;gt;&amp;lt;ESC&amp;gt;
map &amp;lt;leader&amp;gt;eipr o&amp;lt;ESC&amp;gt;ogem &quot;rspec-core&quot;, :path =&amp;gt; &quot;/Users/sam/dev/rspec/rspec-dev/repos/rspec-core&quot;&amp;lt;CR&amp;gt;gem &quot;rspec-expectations&quot;, :path =&amp;gt; &quot;/Users/sam/dev/rspec/rspec-dev/repos/rspec-expectations&quot;&amp;lt;CR&amp;gt;gem &quot;rspec-mocks&quot;, :path =&amp;gt; &quot;/Users/sam/dev/rspec/rspec-dev/repos/rspec-mocks&quot;&amp;lt;CR&amp;gt;gem &quot;rspec-support&quot;, :path =&amp;gt; &quot;/Users/sam/dev/rspec/rspec-dev/repos/rspec-support&quot;&amp;lt;CR&amp;gt;&amp;lt;ESC&amp;gt;

map &amp;lt;leader&amp;gt;eid orequire 'pry'; binding.pry&amp;lt;ESC&amp;gt;
map &amp;lt;leader&amp;gt;li gg/def.*init&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;lcd gg/class.*&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;lrp /^ *p &amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;arp :Ack &quot;^ *p &quot; &amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;apr :Ack &quot;binding.pry &quot; &amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;eal :Align &amp;amp; &amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;eap :Align =&amp;gt; &amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;edc mzO&amp;lt;ESC&amp;gt;j:s/,/,\r/g&amp;lt;CR&amp;gt;(%i&amp;lt;CR&amp;gt;&amp;lt;ESC&amp;gt;%a&amp;lt;CR&amp;gt;&amp;lt;ESC&amp;gt;(%=%:%s/ *$//g&amp;lt;CR&amp;gt;:noh&amp;lt;CR&amp;gt;'zkdd
map &amp;lt;leader&amp;gt;ecl :silent! %s/\[x\]/\[\]/g&amp;lt;CR&amp;gt;gg
map &amp;lt;leader&amp;gt;eae :Align =&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;ea{ :Align {&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;erf i.fetch\x1Blr{r(f]r)
map &amp;lt;leader&amp;gt;erh xea:\x1Bllxxx
map &amp;lt;leader&amp;gt;epl :PromoteToLet&amp;lt;cr&amp;gt;
map &amp;lt;leader&amp;gt;etw mp:%s/ *$//g&amp;lt;CR&amp;gt;:noh&amp;lt;CR&amp;gt;'p
map &amp;lt;leader&amp;gt;ert :%s/\t/ /g&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;orf :call OpenSpec()&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;orv :call VsplitSpec()&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;onrv :call VsplitSpec()&amp;lt;CR&amp;gt;irequire &quot;spec_helper&quot;&amp;lt;CR&amp;gt;&amp;lt;ESC&amp;gt;
map &amp;lt;leader&amp;gt;ors :tabe .rspec&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;ogf :tabe Gemfile&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;ovr :tabe ~/.vimrc&amp;lt;CR&amp;gt;/map.*leader&amp;lt;CR&amp;gt;:noh&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;bi :!bundle install&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;ft zfa
map &amp;lt;leader&amp;gt;uft zR
map &amp;lt;leader&amp;gt;gt :!go test -tags=integration -ldflags -s ./...&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;gb :GoBuild&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;snp :set nopaste&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;sp :set paste&amp;lt;CR&amp;gt;
map &amp;lt;leader&amp;gt;&amp;lt;space&amp;gt; :noh&amp;lt;CR&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A quick scan of this will show you that there are no issues with command prefixing, where if I type part of a command, another command will execute.&lt;/p&gt;

&lt;p&gt;We can visualise some of this as follows this as follows&lt;/p&gt;

&lt;figure class=&quot;kg-card kg-image-card&quot;&gt;&lt;img src=&quot;https://i.imgur.com/GGN9A8X.png&quot; class=&quot;kg-image&quot; alt=&quot;A graph visualisation of some of the leaders&quot; /&gt;&lt;/figure&gt;

&lt;p&gt;What this shows is that there is no sequence of keys that can be pressed that is ambiguous to VIM as to whether or not it should run a command. In addition, not all commands sit at the same level. For example &lt;code class=&quot;highlighter-rouge&quot;&gt;\snp&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;\sp&lt;/code&gt; are of different lengths, but both are terminal and unambiguous.&lt;/p&gt;

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

&lt;p&gt;To quickly conclude: VIM leader commands are a useful tool for vimming faster. You can extract them by finding common sequences you type frequently, and putting them in your &lt;code class=&quot;highlighter-rouge&quot;&gt;.vimrc&lt;/code&gt;. I’ve found this style of organisation, where each letter you type while building a command is a prefix that cannot ambiguously resolve to another command. Thanks for reading!&lt;/p&gt;</content><author><name>{&quot;twitter&quot;=&gt;&quot;penelope_zone&quot;}</name></author><summary type="html">Intermediate to advanced VIM users love to extract common workflows to hotkeys. You might want to optimise workflows like running tests, adding files to git/doing a commit, or reformatting text. The thing is, as you add more and more workflows, organising these hotkeys can become a nightmare. For the past several years, I’ve had a philosophy to organising mine that has really helped me.</summary></entry><entry><title type="html">Rack middlewares that have saved me literally hours of my life</title><link href="https://penelope.zone/2018/12/25/rack-middlewares-that-have-saved-me-literally-hours-of-my-life.html" rel="alternate" type="text/html" title="Rack middlewares that have saved me literally hours of my life" /><published>2018-12-25T15:49:33+00:00</published><updated>2018-12-25T15:49:33+00:00</updated><id>https://penelope.zone/2018/12/25/rack-middlewares-that-have-saved-me-literally-hours-of-my-life</id><content type="html" xml:base="https://penelope.zone/2018/12/25/rack-middlewares-that-have-saved-me-literally-hours-of-my-life.html">&lt;p&gt;In Ruby, &lt;a href=&quot;https://rack.github.io/&quot;&gt;Rack&lt;/a&gt; is our webserver baseline. It is an incredibly simple interface. A rack app is any object which has a public &lt;code class=&quot;highlighter-rouge&quot;&gt;#call&lt;/code&gt; method that takes a single argument, typically called &lt;code class=&quot;highlighter-rouge&quot;&gt;env&lt;/code&gt;, which represents the environment of a HTTP request (params, headers, etc) and returns a three item array containing:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;An integer containing a response code&lt;/li&gt;
  &lt;li&gt;The response headers&lt;/li&gt;
  &lt;li&gt;An object responding to &lt;code class=&quot;highlighter-rouge&quot;&gt;#each&lt;/code&gt; that emits strings to build the response body&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;which represents the response to the request.&lt;/p&gt;

&lt;p&gt;The cool thing about this interface, is that it’s very easy to insert an intermediate object between the request and the app generating the response, “wrapping” it, to modify the behaviour of request processing. These intermediate objects are called Rack middlewares. They have the exact same interface as a rack app, but with one more refinement: their constructor takes the app that they are wrapping.&lt;/p&gt;

&lt;p&gt;This contract between Rack and your code is designed to be easy to understand. What this means is that once you’ve got an idea for a rack middleware you can just type it out. You can quickly write them in config.ru as a Ruby class, and use them by invoking  invoke &lt;a href=&quot;https://www.amberbit.com/blog/2011/07/13/introduction-to-rack-middleware/&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;use&lt;/code&gt;&lt;/a&gt; with the classname of the middleware you want. Once you’ve done those two things you’re good to go. This simplicity makes them very attractive for development and even production debugging.&lt;/p&gt;

&lt;p&gt;What follows is the full source code of a couple of middleware that I’ve created and some explanation of how they’ve made my life much easier.&lt;/p&gt;

&lt;h1 id=&quot;the-potato-middleware&quot;&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;potato&lt;/code&gt; middleware&lt;/h1&gt;

&lt;p&gt;I don’t know why I called it this. When I was working with one of my colleagues, they were like “WTF is potato”. Still, here we are. This is a debugging tool of last resort. Something that you break out when you’re beginning to lose faith that the Ruby programming language functions on a fundamental level.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class Potato
  def initialize(app)
    @app = app
  end

  def call(*args, &amp;amp;blk)
    @app.call(*args, &amp;amp;blk)
  rescue BasicObject =&amp;gt; e
    require 'pry'; binding.pry
  end
end

use Potato
run Rails.application
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Sometimes you can’t work out why an exception is blowing up your app. Sometimes the rails debugger doesn’t kick in. Sometimes you’re tearing your hair out in frustration and you need some help.&lt;/p&gt;

&lt;p&gt;This middleware drops a &lt;a href=&quot;https://github.com/pry/pry&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;pry&lt;/code&gt;&lt;/a&gt; at the very outer most layer of your app. I’m a big fan of the pry debugger, as it lets you deeply investigate the state of a bunch of things in your application. Putting it here at the very outermost level of your application lets you be certain that you’re bypassing anything Rails has introduced, or anything else that might be in the way making it harder for you to debug your application. This middleware has enabled me to better understand what’s going on in my application a number of times.&lt;/p&gt;

&lt;h2 id=&quot;stackprof-middleware&quot;&gt;Stackprof middleware&lt;/h2&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class ProfilerMiddleware
  def initialize(app)
    @app = app
  end

  def call(env)
    if env[&quot;QUERY_STRING&quot;].to_s.include?(&quot;stackprof&quot;)
      StackProf.start(mode: :wall, interval: Integer(ENV.fetch(&quot;STACK_PROF_INTERVAL&quot;], &quot;250&quot;), raw: true)
    end

    result = @app.call(env)

    if env[&quot;QUERY_STRING&quot;].to_s.include?(&quot;stackprof&quot;)
      StackProf.stop
      file_name = &quot;/tmp/foo.txt&quot;
      StackProf.results(file_name)
      result = [200, { &quot;Content-Type&quot; =&amp;gt; &quot;text/plain&quot; }, [File.read(file_name)]]
    end

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

&lt;p&gt;This one’s a little more complicated. &lt;a href=&quot;https://github.com/tmm1/stackprof&quot;&gt;Stackprof&lt;/a&gt; is one of my all time favourite profiling tools in Ruby. At DigitalOcean, we run a lot of our apps in docker containers on kubernetes. Which means that we can’t just SSH in and introspect running processes or the file system. I needed a way to be able to profile the execution of a request, in production, and get the results back. This is what I came up with.&lt;/p&gt;

&lt;p&gt;When this middleware is installed if you include &lt;code class=&quot;highlighter-rouge&quot;&gt;stackprof&lt;/code&gt; anywhere in the URL query string, the response body gets replaced with the result of a profiling run. You can then use this to &lt;a href=&quot;http://www.brendangregg.com/FlameGraphs/cpu-mysql-updated.svg&quot;&gt;generate flamegraphs&lt;/a&gt; or &lt;a href=&quot;https://github.com/tmm1/stackprof&quot;&gt;other useful profiling information&lt;/a&gt;. We don’t directly put this in to customer facing applications in production, but it’s been very useful for performance improvements in internal applications.&lt;/p&gt;

&lt;h1 id=&quot;unicorn-worker-killer&quot;&gt;Unicorn worker killer&lt;/h1&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/kzk/unicorn-worker-killer&quot;&gt;Unicorn worker killer&lt;/a&gt; can be configured to kill individual unicorn workers when they’ve either served a certain number of requests, or a certain amount of memory. I didn’t write this one, but it’s been useful to me to improve the stability of my production applications. Frequently, you’ll observe that a unicorn stops responding to requests to some reason. Generally speaking, I’ve found that rebooting processes in production frequently is a way to make them more stable, and so this is just a convenience wrapper for that. If you’re not using Unicorn, you probably don’t need this.&lt;/p&gt;

&lt;p&gt;So there you have it, a few rack middlewares, two that you can write by hand, one that you can install from a gem, that are very useful. Thanks for reading!&lt;/p&gt;</content><author><name>{&quot;twitter&quot;=&gt;&quot;penelope_zone&quot;}</name></author><summary type="html">In Ruby, Rack is our webserver baseline. It is an incredibly simple interface. A rack app is any object which has a public #call method that takes a single argument, typically called env, which represents the environment of a HTTP request (params, headers, etc) and returns a three item array containing:</summary></entry><entry><title type="html">Tensorflow journal, part 1</title><link href="https://penelope.zone/2018/12/25/tensorflow-journal-part-1.html" rel="alternate" type="text/html" title="Tensorflow journal, part 1" /><published>2018-12-25T15:49:14+00:00</published><updated>2018-12-25T15:49:14+00:00</updated><id>https://penelope.zone/2018/12/25/tensorflow-journal-part-1</id><content type="html" xml:base="https://penelope.zone/2018/12/25/tensorflow-journal-part-1.html">&lt;p&gt;Hi Folks. This is a little post where I’m leaving a bunch of single line notes of things I’ve found useful in tensorflow, for image based tasks. &lt;em&gt;I mostly have no idea what I’m doing&lt;/em&gt;, but I’ve found some things while working on it that work well for me. Maybe you’ll find this useful!&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The &lt;a href=&quot;https://www.tensorflow.org/api_docs/python/tf/train/RMSPropOptimizer&quot;&gt;RMSPropOptimizer&lt;/a&gt; seems to be very good for a wide range of tasks. &lt;code class=&quot;highlighter-rouge&quot;&gt;0.001&lt;/code&gt; seems to be a good default learning rate&lt;/li&gt;
  &lt;li&gt;Deeper networks need more training rounds to converge. Anecdotally, doubling the number of training rounds per layer (1000, 2000, 4000, etc) seems to be good&lt;/li&gt;
  &lt;li&gt;The &lt;a href=&quot;https://hacktilldawn.com/2016/09/25/inception-modules-explained-and-implemented/&quot;&gt;inception module&lt;/a&gt; is a very good tool for image discrimination tasks (e.g. recognition, the discriminator in a GAN, the encoder layer in a VAE). Most of the implementations on the internet are complicated. &lt;a href=&quot;https://gist.github.com/penelopezone/e6765afa1b75ba90732729c96072543a&quot;&gt;here’s mine&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Directly connecting &lt;a href=&quot;https://www.tensorflow.org/api_docs/python/tf/layers/dense&quot;&gt;dense&lt;/a&gt; layers to undownsampled convolutional networks will cause a computational complexity/memory explosion. As a rule of thumb, a dense layer should have no more than 2048 inputs.&lt;/li&gt;
  &lt;li&gt;If you’re building a GAN or VAE, &lt;a href=&quot;https://towardsdatascience.com/implementing-a-generative-adversarial-network-gan-dcgan-to-draw-human-faces-8291616904a&quot;&gt;DCGAN&lt;/a&gt; has a very good decoder layer. &lt;a href=&quot;https://gist.github.com/penelopezone/d0c5c79f6db3c903ec06dd9a4110c6ef&quot;&gt;here’s my implementation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;When you’re building a GAN or VAE, all the output looking exactly the same for the first few hundred generations is pretty normal, don’t worry, give it some time.&lt;/li&gt;
  &lt;li&gt;Visualise everything&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.tensorflow.org/api_docs/python/tf/nn/sparse_softmax_cross_entropy_with_logits&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;tf.nn.sparse_softmax_cross_entropy_with_logits&lt;/code&gt;&lt;/a&gt; is the right loss metric for when your classification problem has exclusive classes (e.g. MNIST)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;please hit me up on twitter &lt;a href=&quot;https://twitter.com/penelopezone&quot;&gt;@penelopezone&lt;/a&gt; if any of this strikes you as wrong!&lt;/p&gt;</content><author><name>{&quot;twitter&quot;=&gt;&quot;penelope_zone&quot;}</name></author><summary type="html">Hi Folks. This is a little post where I’m leaving a bunch of single line notes of things I’ve found useful in tensorflow, for image based tasks. I mostly have no idea what I’m doing, but I’ve found some things while working on it that work well for me. Maybe you’ll find this useful!</summary></entry></feed>