Latest Posts from csaunders


Thoughts after first few days of classes

I recently quit my job to pursue a career in the brewing industry and that journey began for real on this past Monday when I finally started the Brewery program at Niagara College. I’ve been a little nervous about getting back to school and how things would go once I got there, but so far things have been good. I’ve scraped high level ideas from my years of brewing, and now I’m going to have the time to dig into the guts of everything and get a stronger understanding of parts of the process that I’ve never really bothered myself with up until now. The people teaching all of the brewing classes have amazing histories in the industry such as 20+ years doing QA at Labbatt. I’ve yet to experience all my classes, but so far all the brewing ones have been wonderful.

The knowledge in the class varies from very little to quite a bit and several of my classmates already have careers working in the industry and are looking to level up what they are doing. And even though some of us have never worked for real in a brewery, we still got to do that on our second day of classes. While the schedule said we’d only be there for three hours, we were there until almost 4. Though, if you’ve ever brewed beer before it makes sense, since a typical brew day from setup to tear down on takes at least 5 hours on a home-brew setup. There were a few hiccups on that day so our day got extended by a bit, but it wasn’t a huge deal. The group I was in was slotted to work on a craft setup that you’d see in a commercial brewery, so we got to learn learn about all the valves and levers and how they are to be used. Even on such a small system the amount of information to absorb was overwhelming. Valve configuration is super important and pulling the wrong one could result in losing a batch of beer, sending wort to the wrong location or even getting severely injured. Though, the program takes safety pretty seriously so they make sure that we have an understanding of all the things we need to do and how to do it safely.

Working on the craft system was a bit awkward because everyone needed to learn about how it all works. So there was a lot of downtime, but the day still went by extremely fast. We had time to process the information, talk about brewing and do a few small tasks. In the coming weeks our groups are going to be split up into a bunch of work around the brewery which should be pretty rad. The work will vary from brewing on the craft system, so packaging products for distribution in the tasting room and bottle shop.

I’m going to be learning a lot in the next 16 months, and I’m looking forward to all of it.


My 2014 In a Nutshell

Taken while walking around the border between east and west Berlin during the Red Berlin Tour.

Now that I sit down and think about it, 2014 was a pretty solid year. Although the early part of the year is pretty fuzzy for me, the rest I can remember quite well.

Adventures

– Spent 2 weeks travelling to Brussels and Ghent in Belgium, Amsterdam and Berlin
– Got back into camping and fully disconnected
– Went fishing for the first time in 10 years
– Met a bunch of awesome people while travelling around Belgium
– Got into an axe throwing league
– Rode a bike on the same tarmac that was used during the Berlin Airlift

Beer

– Learned to appreciate the Trappist style
– Went to the Cantillon Brewery to learn and understand what makes Lambics
– Got to hang out with one of the brewers from Bellwoods and learn about the care they put into making every batch
– Took a course to learn about off-flavours and how to identify them. Here is where I learned that I’m blind to diacetyl.

Homebrewing

– Downsized my fermentation vessel so I can get back into brewing more frequently
– Used Belgian ale yeast for the first time (with excellent results)
– Gave some friends a hands on “how to brew” experience

Reading

– Count Zero
– Rise of the Meritocracy
– Feminism is for Everybody
– Wherever you go, there you are
– Mans Search for Meaning
– Agile Retrospectives: Making Good Teams Great
– Release It!
– Growing Object-Oriented Software, Guided by Tests
– Eloquent Ruby
– Clean Code

Programming

– Participated in the Toronto Global Game Jam as the developer to build Pride and Pistols
– Participated in Ludum Dare 31 to create Guiding Light
– Tried my hand at building a rogue-like
– Started building a replacement for the ruby theme gem

There might more that I’m forgetting, but these are some of the things that stood out the most to me from the past year. I’m planning on being a bit more rigorous with journaling, and hopefully there’ll be more to remember for 2015.


Going on Sabbatical

In the next few weeks I’ll be taking a few months off from my regular job. I’m going to be logging everything I’m doing on a site dedicated to my Sabbatical.

If you are interested in checking it out, I suggest you add it to your sites you watch. It does have an RSS feed, so you can always subscribe to that if you want.

learningtolearn.sndrs.ca


My ArrrrCamp Picks

Confreaks recently released the ArrrrCamp 2014 presentations and I wanted to share the talks that I found to be pretty awesome. That’s not to say that this wasn’t the case for all the talks, they were all pretty rad, but curated lists might help get you started.

Here they are, not in any particular order:

Also if you want, you can watch me try to explain how to do asynchronous programming during the lightning talks

 


Phoenix: Cross-Platform Theme Utilities for Shopify built with Go

When it comes to programming, my go to project has been Shopify theme synchronization. As the active maintainer of the shopify_theme gem, I’ve been dealing with some interesting and exhausting issues, some of which are easier to solve than others.

The design of the theme gem leaves a lot to be desired and adding new features has become harder and harder. Another problem I’ve noticed with many of the people trying to use it has been how difficult it is to install across various platforms. Believe it or not, but there’s a decent number of designers on the Windows platform, and getting the Ruby and shopify_theme working on their system is a journey.

In my spare time I’ve been learning the Go programming language over the last year where I’ve built some toys and tried my hand a crappy rogue-like. Along the way I made lots of mistakes and the designs were terrible, but it was a learning experience.

With the lessons I’ve learned from those projects and from reading some good articles on structuring Go projects I dove into building what I hope will be the theme development tool.  Currently the project isn’t fully in line with the Ruby version, though I do feel that it has enough features to be useful for someone looking to build a theme. Those features are:

If you are a Go programmer and are interested in sharing your insights, I’d love to hear from you. I’m very green and would love some feedback on how to improve the project.

If you are a theme designer, please let me know that you are interested in the project. I’ll work on getting builds out for the various systems as soon as possible!

Check out the project on Github!


Asynchronous Programming with Goroutines in Ruby

pipeline

I’ve been programming on and off in Go for a little while now, and I came across a gem that makes it possible to use channels and threaded functions for sequential processing. The gem is called “agent” which was originally written Ilya Grigorik. It provides a number of extensions to the Kernel such as go! and channel!.

Overview

What is a channel?

Channels aren’t really a new idea, they came out of a research paper1 called Communicating Sequential Processes. They became really popular when the Go programming language came out in which channels are a core construct of the language and really the way most of your work is done.

Channels are able to hold units of data, called messages which allow other relevant parties to listen on. A channel has two “ports” one for pushing data into and one for pulling data out of. They are also atomic, so there is no need to worry about a read or write resulting in something inconsistent, such as getting the same message twice.

In agent a channel can optionally be buffered. Using a buffered channel allows you to write a message to it without having to worry about immediately blocking. Otherwise a channel has a buffer size of zero, which means that writing to the channel blocks until someone decides to read from it. Knowing how your channels work is extremely important, which will be covered in “Ugh Deadlock“.

require 'agent'

# Create an unbuffered channel
unbuff = channel!(String)

# Create a buffered channel
buff = channel!(String, 1)

# Write to the channels
buff << "Hello Unblocking World"
# Execution blocks until someone reads from it
unbuff << "Hello Blocking World"

What does a goroutine do?

In the Go programming language a goroutine is “the execution of a function call as an independent concurrent thread of control, […], within the same address space”. You can think of them as threads but don’t need to worry too much about the details. Also if the function provided is a lambda, you get the benefits of closures.

In Ruby the benefits are very much the same, we are passing in a block of code to the go! method call. This method takes care of all the gross bits of threading for us, though if you grab onto the result of the go! call you’ll see that we aren’t working with any magic language construct, just a thread.

goroutine = go! { sleep(5); }
puts goroutine.inspect
# #<Thread:0x007fbf66ed5508 sleep>

In practice though, you don’t need to worry about this. You’ll invoke your goroutine and carry on your merry way.

How can the two be used together?

Goroutines and channels become very powerful because they allow us to communicate asynchronously. There are lots of ways to handle work that might be slow, such as jobs that create other jobs in a system like Sidekiq. While this approach works, it results in systems that are difficult to understand because of the separation.

Instead we can use channels as a tool to let other aspects of our pipeline know when they can start the next stage of processing. Since the channel becomes the method of communication, we can write our code in a way that makes it look sequential even though when we actually execute it, it will be running asynchronously. This takes a huge load off of our brains, which get really fuzzy when dealing with asynchronicity.

Consuming a channel

Let’s say we are building a system that makes strawberry rhubarb pies. If we were to make a pie on our own it would look something like this:

  1. Cut together flour and shortening to make the dough
  2. Clean strawberries and rhubarb removing all dirt
  3. Quarter strawberries and chop rhubarb into cubes
  4. Roll out dough and place enough to cover the bottom of your pie tin. Trim the edges
  5. Measure out 2 cups of strawberries, 2 cups of rhubarb and 1 cup of white sugar
  6. Mix measured strawberries, rhubarb and sugar together until even
  7. Pour mixture on top of dough
  8. Cover pie with other piece of dough and make some cuts to let steam out
  9. Place in oven

For a family friendly baking day, doing this synchronously is no big deal. You have a good time, make some pie and all is fabulous. But if we are looking to crank out pies as quickly as possible, this just won’t do. We need to split this up into a bunch of separate pieces. Looking at the process we can make a few optimizations:

  1. A person makes the dough, and prepares the tins as well as the pie cover
  2. A person cleans, cuts and mixes the fruits into the required portions. Let’s say they place them in bowls that someone can just grab.
  3. A person that prepares the pies and places them in the ovens. For simplicity we are going to assume that we have unlimited space in our ovens.
PreparedTin = Struct.new(:bottom, :top)
MixedFruits = Struct.new(:mixture)
RawPie      = Struct.new(:bottom, :mixture, :top)

class Pie
  def initialize(slices=6)
    @slices = slices
  end

  def take_slice
    if slices?
      @slices -= 1
      "slice o pie"
    end
  end

  def slices?
    @slices > 0
  end
end

class Oven
  def initialize(chan)
    @completed = chan
  end

  def bake(pie)
    go! do
      sleep(10)
      @completed << Pie.new
    end
  end
end

prepared_tins  = channel!(PreparedTin)
mixed_fruits   = channel!(MixedFruits)
completed_pies = channel!(Pie)
oven           = Oven.new(completed_pies)

# Prepare our Pie Tins
go! do
  loop do
    dough = mix_flour_and_shortening
    dough = roll_out_dough(dough)
    top, bottom = cut_dough(dough)
    prepared_tins << PreparedTin(top, bottom)
  end
end

# Prepare our Mixed Fruits
go! do
  loop do
    strawberries   = clean(Strawberry.new)
    rhubarb        = clean(Rhubarb.new)
    sliced_berries = quarter(strawberries)
    cubed_rhubarb  = cube(rhubarb)
    sugar = measure(Sugar.new)
    mixture = mix(sliced_berries, cubed_rhubarb, sugar)
    mixed_fruits << MixedFruits.new(mixture)
  end
end

# Bake our pies
go! do
  loop do
    # Receiving from an agent channel returns a pair
    # so if we were to receive and not call first
    # we'd get something like [#PreparedTin, true]
    #
    tin = prepared_tins.receive.first
    fruits = mixed_fruits.receive.first
    raw_pie = RawPie.new(tin.bottom, fruits.mixtures, tin.top)
    oven.bake(raw_pie)
  end
end

# Eat our pies
go! do
  pie = nil
  loop do
    pie ||= completed_pies.receive.first
    if pie.slices?
      puts "Om nom nom a #{pie.take_slice}"
    else
      # Throw out the tin, this pie is dead to us
      pie = nil
    end
  end
end

So here we’ve gone and created 4 workers. One prepares the pie tins, another prepares our pies contents, another who puts the pies together and bakes them and finally, someone to consume all those pies. The code can be read from top to bottom, and we really don’t need to worry about concurrency all that much.

Ugh Deadlock

We need to be very careful when working with channels because we run the risk of deadlocking our system. Luckily the library has built in protections that will raise exceptions when a deadlock is detected.

f = channel!(String)
go! { f << "Hello World" }
f.receive # ["Hello World", true]
f.receive # Raises Exception
# #<Class:0x007fefc38dc768>: No live threads left. Deadlock?

Sometimes these can catch us off guard but do not fret, there are plenty of ways to get around this. We can use select! which is a based off a similar function for the Go language. select acts very similar to a case statement, though the big difference is that they are used for communication operations and this allows us to conditionally act on messages sent to different channels.

In agent we are also able to use a timeout which allows our select! to stop blocking on channels. For example, we can use select! with a timeout that will ensure we don’t deadlock.

select! do |s|
  s.case(f, :receive) { |result| puts result }
  s.timeout(0.1) { puts "Exceeded 100ms timeout!" }
end

Caveats

In the Go programming language you can put whatever you want on a channel. Because the system is statically typed it knows how big each message is going to be. In agent this isn’t the case and there appears to be some marshalling going on under the covers. I came across this problem while trying to send objects that wrapped Nokogiri on some channels.

require 'agent'
require 'nokogiri'
require 'rest-client'

pages = ["http://github.com",
    "http://bitbucket.org",
    "http://sourceforge.net"]

class Result
  def initialize(data)
    @doc = Nokogiri::HTML(data)
  end

  def title
    @doc.css('title').first
  end
end

results = channel!(Result, 3)

pages.each do |page|
  response = RestClient.get(page)
  results << Result.new(response.body) # Raises error
  # agent/push.rb:8:in `dump': no _dump_data is defined for class Nokogiri::HTML::Document (TypeError)
end

processing = true
while processing do
  select! do |s|
    s.case(results, :receive) { |r| puts r }
    s.timeout(5) { processing = false }
  end
end
puts "done"

After looking around a bit I figured that it was just the objects cannot be marshalled. I was caught off guard by the issue, but I was able to come up with a work around by simply using a Hash instead. I haven’t tried doing anything with value objects yet, but I don’t see why those would cause any problems either.

In Conclusion

The agent library was an excellent way to approach the asynchronous programming problem in Ruby. It’s got some rough edges that might cut you, but with the right understanding of the limitations you can easily work around them. Other than that it’s a fabulous way to learn about this alternative approach to programming. I’d even go as far to say this could be a gateway into the Go programming language since it helps you establish the basics of using goroutines and channels to communicate.


Building a Test Suite in Scheme

lisp
Although I don’t get to write in them a lot, I love LISPs. The language is amazingly simple and effectively a white canvas that you can build anything in.

This weekend I hopped back into reading The Structure and Interpretation of Computer Programs (SICP) and started implementing some of the problems. I was constantly copying and pasting (or worse, retyping) my test code. This was getting a little annoying so I figured I could implement a simple test suite to verify my algorithms are working.

Building a test suite in a language isn’t hard; heck, the Ruby testing library Minitest is a good example in the simplicity. There are lots of features you can build out, but for academic purposes, building a test suite shouldn’t be too tricky.

For my Scheme test suite the only thing I needed to do was ensure that each test returned true or false. If it’s false, then I know the test failed and I could act appropriately. The simplest way we can define our suite of tests would be a list of function names that we evaluate.

;; I am using the Racket Scheme Implementation
(define (suite cases)
    (if (eq? cases null)
        ("Test Suite passed Successfully!")
        (let ([testcase (car cases)])
            (if (testcase)
                (suite (cdr cases))
                (failure testcase)))))
(suite (cons test1 (cons test2 (cons test3 null))))

(define *tests* null)
(define (test code)
    (set! *tests* (cons code *tests*)))

While the above implementation works, it is pretty nasty to look at. It would be cool if we had a nicer way to define our tests. My first stab at the implementation simply used a global tests variable that I would append my test functions to. I had to major problems with this implementation: unnecessary test noise and tricky reporting. The noisy tests meant I needed to do two things in order for a test to be registered:

(define (pascal row col) -1)
(define (pascals-triangle-0-0) (= 1 (pascal 0 0)))
(test pascals-triangle-0-0) ;; ಠ_ಠ

I could’ve tried getting around it by simply passing in lambdas, but my suite didn’t have a good way of reporting which test had failed. Running a failing suite with a lambda in it would result in the following:

(suite (cons (lambda () #f) null))
;; "Test failed #<procedure>"

Well that’s not very handy so what if we were to take a different approach to building out these tests. Instead of our test simply taking a function, let’s pass in the name of the test and the code to run:

(define (test name code)
        (set! *tests* (cons (cons name code) *tests*)))

(define (suite cases)
    (if (eq? cases null)
        (pass)
        (let ([testcase (car cases)])
            (if ((cdr testcase))
                (suite (cdr cases))
                (fail (car testcase))))))
(test
    "that 1+1 is 2"
    (lambda () (= 2 (+ 1 1))))
(suite *tests*)
;; "Test Suite Passed sucessfully"
(test
    "that 2+2 is 5"
    (lambda () (= 5 (+ 2 2))))
(suite *tests*)
;; "Test failed that 2 + 2 is 5"

And with that is a super simple test suite. For more complicated tests it probably wouldn’t stand up, but for the kinds of functional programming I’ve been doing along with SICP it should work out alright.


Mental Health and Toxic Communities

From Model View Culture about Toxic OS Communities.

We need more stories of people leaving toxic communities so that people know it’s ok to prioritize their mental health over their community. We need stories of successfully switching jobs, of abandoning positions of power to protect our mental health or get a better work-life balance.


Curious Cat

curious_cat

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Canada License.
Permissions beyond the scope of this license may be available at http://sndrs.ca.

 


Landing in a Storm

Landing in a Storm

I wouldn’t say this is the best photography I’ve done and it was super hard to get the focus right on the spot, but I wanted to share a shot from a pretty cool light show I got to see that made me decide to stay up a little bit longer.

I need to spend some more time using my equipment so I can get some better in the moment shots like this in the future.

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Canada License.
Permissions beyond the scope of this license may be available at http://sndrs.ca.