My current $JOB uses JIRA to manage issues and Github as the forge. I use Jujutsu and create remote branches using jj git push -c @ . However, the Engineering Standard at work requires that the branch be named in an identifiable way. In practice, every branch is the slug of the commit description. After doing creating a jj bookmark manually a few times, I decided to automate it.
My dotfiles setup is very simple: I version control my $HOME directory using git. I ignore everything by default to avoid accidentally adding files I do not want to track. This avoids the need for any scripts or frameworks. Lately, I have been using Jujutsu for more personal projects and decided to use jj to manage my dotfiles.
Ruby on Rails defined the ethos of the web development community for many years. I have observed people trying to replicate "Rails" in other languages with very mixed results. I consider Laravel, ASP.NET and Phoenix successful rails-like frameworks. Python already has Django. Sadly Java, Kotlin, Scala, Node.js, Go and Rust all lack a widely adopted rails-like experience.
Hyper supports sending HTTP/1.1 Chunked Trailer Fields as of v1.1.0 . The http-body is now at v1.0 as well and uses frames to allow a stream to return data and trailers.
I was reading How fast is your shell? and it got me thinking about the difference types of speed developers prioritize. A lot of articles and advice focus on initial startup, which can be thought of as acceleration . We should also consider, what happens after we are done accelerating, how easy it is to maintain our velocity.
I saw this statement in an accepted answer on Stack Overflow: Retrieving the value of an environment variable will incur a system call. source This answer surprised me as I did not think this was the case. There is an edit farther down that has links to other Stack Overflow posts saying get getenv does not make a syscall. Let us prove it ourselves.
At work, I lead a team responsible for a Node.js service that serves a lot of GraphQL queries. We recently noticed some servers in the cluster were running much slower than others. We had used 0x in the past to profile Node.js services locally. In this case, we could not identify the problem locally and needed a solution to profile Node.js in production to identify the cause of the slowdown.
Hyper is designed to support streaming bodies. The current version of axum, v0.6, supports streaming a response. If we want to include trailers (sometimes called "trailing headers") then we need to implement our own custom body.
I have been familiar with the concept of Command Query Responsibility Segregation (CQRS) for a while, but did not truly understand its practical application until I read The Log: What every software engineer should know about real-time data's unifying abstraction by Jay Kreps.
A webhooks allow two applications to communicate events. It is relatively simple to get started using webhooks using HTTP and JSON. However, there a number of failure scenarios that developers should be aware of in order to make their webhook implementation robust.
At work, I recently inherited a node service that was sending metrics to DataDog using the brightcove/hot-shots StatsD client. While investigating some issues with dns.lookup , I noticed other people had run into this same issue but there was no one sharing what a solution might look like.
A company often has a landing page for first time visitors that is optimized for describing and educating that person on what product or service the company is offering. This page is usually not useful for people already familiar with the company. Ideally, a new user would see the marketing landing page and the returning user would see a more functional page. There are two common approaches to…
When writing tests, we do not want to hit the external API each time we run our tests. If we are coming from a dynamic language, such as Node.JS, we may want to a solution like fetch-mock which will patch the implementation of fetch at runtime. This is not practical in Rust. There are some attempts, like the hotpatch crate, but we will use a different strategy.
Lucet is Fastly's native WebAssembly compiler and runtime . Using the Lucet runtime and Rust's wasm32-unknown-wasi target, we can create a WASM program that runs on the server.
Lucet is Fastly's native WebAssembly compiler and runtime . I am a big fan of Rust, Fastly and WASM. Especially WASM on the server via WASI . I jumped right in and tried to get my own lucet program running, but the setup is a rather long process. My plan was to introduce lucet to some colleagues at my local Rust meetup. I am a huge fan of Rust, but the compile times are an issue. Spending 30…
I started writing mob, an multi-echo server using mio, in 2015. I coded mob into a mostly working state and then left it mostly alone, only updating it to work with the latest stable mio. Recently, I started looking at the code again and had the urge to improve it. In a previous post , I talked about managing the state of connections in mob. In this post, I will walk through what I did to remove…
I was looking to use the mspc queue that comes in the future crate in weldr . Weldr uses hyper (which uses tokio), so it makes sense to use tokio's Core as the executor. I did not have a good understanding of how this futures based mpsc queue worked. It has some subtle differences from the mpsc queue in the std library. I spent some time reading the documentation on…
Note: This project was originally named alacrity . Over the past few months I have been working on a building a reverse proxy, called weldr , in Rust. I have just published the initial release of weldr. I have been interested in doing something with networks in Rust. I have spent a lot of time building hypermedia APIs, so doing something with HTTP seemed like a good fit. I started out using mio…
If you have spent any amount of time learning Rust, you quickly become accustomed to Option and Result types. It is through these two core types that we make our programs reliable. My background is with C and dynamic languages. I found it easiest to use the match keyword when working with these types. There are also combinator functions like map and and_then which allow a set of computations to be…
This is an introduction to a parsing library called nom . The nom crate is written by Geoffrey Couprie, aka Geal , and is a remarkably complete and powerful library for building parsers. I recently did a lot of parsing of bytes on the wire for my carp library and it was a lot of work. I wish I had come across the nom library before I had done all of that. The description of nom is a Rust parser…
Note: This blog post does not work with rustc 1.19.0 or later due to a regression in rust 1.19.0. Use the following to set rust 1.18.0 up: $ cd /path/to/project $ rustup install 1.18.0 $ rustup override 1.18.0 In this post we are going to hook our basic webservice up to a database. The webservice will accept a request for /orders , query the database for orders and return a…
In this post I am going to walk through the creation of a webservice in Rust. This is a Getting Started post that will serve as a foundation for future posts. The webservice will return a static json response to start. There are a few different options for web frameworks in Rust, but practically all of them use the underlying HTTP library called hyper . I am most familiar with nickel , so we will…
When building a foreign function interface to C code, we will inevitably run into a struct that has a union. Rust has no built-in support for unions, so we must come up with a strategy on our own. A union is a type in C that stores different data types in the same memory location. There are a number of reasons why someone may want to choose a union, including: converting between binary…
I was writing some Rust with a colleague when they asked me about the cases where Rust deferences types for us automatically. I said that Rust will automatically dereference pointers when making method calls , but otherwise there was no compiler magic. This conflicted with their experience with Rust and presented an example like this: let a = 1 ; let b = 2 ; let c = a + &b; The basic question is:…
I would wager most people who choose mio to solve their async IO problems are expecting more abstraction in the library. The oft repeated question of Why doesn't mio have callbacks? is evidence of this. In fact, it is a design goal of mio to add only as much abstraction necessary to provide a consistent API for the various OS async IO implementations. A consequence of this design decision is…
Tested on Rust 1.3 Here is a high level of example of how to make a HTTP GET request to some URL. To make the example a little more interesting, the URL will have a json response body. We will parse the body and pluck some values from the parsed json. There are a number of crates we could use to make an HTTP GET request, but I am partial to curl . The curl library should be familiar to a wide set…
This post is going to walk through establishing a simple protocol when using mio. Let us first talk about why a protocol is needed. There are two common network protocols in use today: UDP and TCP. UDP is a message oriented protocol that delivers the message in one chunk. The downside to UDP is that there is no guarantee of message delivery because UDP does not handle packet loss. Many people want…
I use a MacBook Air as my main laptop. I have been using Vagrant to test rust programs on linux. This feels a little heavy to me though as I have to create a Vagrant machine for each repository. The up and halt phases of the Vagrant box are a little slow and each machine eats away at my available hard drive space. I do not need an entire virutalized operating system, just a place to test my…
I am going to walk through the creation of a PHP extension that works with a Rust library. I have a working example here. I also created a PHP extension for my Rust selecta port . Both examples use the same foreign function interface (ffi). I made sure to pick an example that uses strings because strings add additional complexity that numbers do not introduce. Before Getting Started note: I…
This is my second blog post in a series about async IO. You may want to read first blog post if you are not familar with mio or epoll/kqueue implementations. Basic Setup At the time of this writing, I am using the newly released mio 0.4.x . Until recently if you got mio from crates.io, then you will get 0.3.x . There are breaking changes between these two releases. I have a complete working…
I really like _with style functions that accept a FnOnce callback. The scoping rules work out really well when using these functions. I was working with the slab crate recently and used the Slab#insert_with function. This function takes a callback where an object is supposed to be allocated before being inserted into the slab. The function returns an Option type. I was trying to figure out to drop…
I needed async IO for a Rust project I was working on. My server needs to read some bytes from a client and then send those bytes back to all registered clients. I decided to use mio , the Rust async IO library, to build a server. All the examples I found showcased reading from a socket and then writing back to that same socket. Also, many of the examples had caveats about unhandled edge cases and…
In Rust, you quickly learn that vector and slice types are not iterable themselves. Depending on which tutorial or example you see first, you call .iter() or .into_iter() . If you do not realize both of these functions exist or that they do different things, you may find yourself fighting with the compiler to get your code to work. Let us take a journey through the world of iterators and figure…
The rules around references and borrowing in Rust are fairly straight-forward. Given an owned variable, we are allowed to have as many immutable references to that variable as we want. Rust defaults to immutability, so even functions like trim are written in such a way that the result is a reference to the original string: fn main () { let name = " Herman ". to_string (); let trimmed_name = name.…
Russian Translation We learned how to create a function that accepts String or &str as an argument. Now I want to show you how to create a function that returns either String or &str . I also want to discuss why we would want to do this. To start, let us write a function to remove all the spaces from a given string. Our function might look something like this: fn remove_spaces ( input : & str ) ->…
Russian Translation In my last post we talked a lot about using &str as the preferred type for functions accepting a string argument. Towards the end of that post there was some discussion about when to use String vs &str in a struct . I think this advice is good, but there are cases where using &str instead of String is not optimal. We need another strategy for these use cases. A struct…
Russian Translation For all the people frustrated by having to use to_string() to get programs to compile this post is for you. For those not quite understanding why Rust has two string types String and &str , I hope to shed a little light on the matter. Functions That Accept A String I want to discuss how to build interfaces that accept strings. I am an avid hypermedia fan and am obsessed about…
I listened to the Changelog podcast on Rust recently and loved the remark about enabling web developers to get into systems programming. I have been thinking about the way we design code in the web world versus the way we design code in Rust. In the web world, we often use a hash/dict/map to hide hard-coded values behind a nicer interface. Consider an example where you would want to…
As soon as I started writing implementations for structs in Rust I started fighting with the compiler. Writing what seemed like a simple getter function caused me a lot of frustration. The self parameter can really throw me off in Rust. I reflexively treat it like this in C++, which has no concept of & or &mut . I do this because I think of impl Person as defining methods on a class as I would do…
I was writing some code in Rust and wanted to get the size of my terminal. This is currently not implemented in Rust though. I decided to read up on The Foreign Function Interface Guide to figure out how to do it myself. The Foreign Function Interface (FFI) is how Rust code interfaces with native C code. I also found a great Stack Overflow post that showed me how to write native C to get the…
The nickel.rs Web Application Framework for Rust is inspired by the popular node.js express framework. The stated goal of the nickel.rs framework is to show people that it can be easy to write web servers using a sytems language like Rust. I have been using the framework to create hypermredia examples using my hal-rs library. One of the downsides to a systems language like Rust is the verbosity of…
My notes from Emberconf . Opening Keynote Open source communities value contributions that are not just code. --- Yehuda Katz Robert Jackson contributed a lot of works to making the 6 week release process much more automated. A number of people worked to create ember-cli tooling. Jo Liss created Broccoli. Leah Silber organized Emberconf. I believe a successful team requires more than just someone…
The Mink extension to behat makes it really easy to test the contents of a page. I can use the assertElementContainsText feature to assert that some text exists within a certain element: {% highlight gherkin %} Then I should see "My Page Title" in the "h1" element. {% endhighlight %} If there is more than one h1 element on the page, I can use a css selector to increase specificity: {% highlight…
This blog post is in response to the discussion started by the tweet below: Incidentally, MVC is a REALLY poor fit for designing hypermedia services. So that's fun, everyone who thought you knew what you were doing. — Nate Abele (@nateabele) January 3, 2014 This post is not intended to present the best way to design and build hypermedia services. My goal is present a high level…
Dave Ramsey has a famous quote: "The only ship that won't sail is a partnership" (source) . I believe the context is in regards to two friends starting a business together. I recently heard this together and wondered how many succesful startups were partnerships. I did a quick search on CrunchBase for startups that were acquired for over 1 million dollars since January 2010. The results show…
The principle of Don't Repeat Yourself (DRY) is more than just grouping common code together. When trying to apply the DRY principle, it is easy to start making a mess of a class interface. I recently had to write some code to generate Flickr image URLs from an API response. I needed to generate two types of URLs: a thumbnail and a normal image. Here is one version of code reuse: {% highlight…
I think the Object Oriented (OO) principle of Don't Repeat Yourself (DRY) is often misunderstood. In particular, the word "repeat" is troublesome. It has nothing to do with minimizing the amount of code you write. It is also not about merging similar methods together into a super-method. The DRY principle is about preserving a single source of truth in a system. When a there are multiple…
I have always wondered why the MySQL datetime type only has second precision. Developers will happily put a datetime type in a unique index though. They justify that decision by telling themselves, "Two rows inserted within the same second will never happen". That same developer just got done reading the latest MongoDB article that benchmarked a gazillion inserts a second. They tweeted it too. I…
I think the SQL is Agile post by Armin Ronacher is a little short sighted. Disclaimer: I rarely use MongoDB or other NoSQL offerings . There are plenty of good reasons to use MongoDB in production. Many people and companies have shown it to be successful. More importantly we should not be afraid of trying out new things, especially for side projects. We should be cautious of trying new things for…
This blog post is inspired by Douglas Crockford's book JavaScript: The Good Parts . All programming languages have warts. That is, there were certain decisions made about a language that are less than ideal. Some people are driven to remove these warts from the language in an attempt to make the language better. I think this is done with the best intentions, but can often have negative…