TMWL Jan’20 — functional Scala, Http4s Timeouts, subtree split in git

Programmers say what they’ve learned

The series — This Month We’ve Learned (at SoftwareMill) encourages us to be more curious, helpful and grateful. Let’s find out what we’ve learned in January 2020: functional Scala, Http4s Timeouts, how to split a git project.

Programmers who share their discoveries this time are:

Marcin Baraniecki — Software Engineer

— Software Engineer Michał Matłoka — Senior Software Engineer and Consultant

— Senior Software Engineer and Consultant Michał Ostruszka— Software Engineer

“Getting Func-ey” — a series of articles by Mat Fournier (@mat4nier) — Marcin’s January inspiration

I’ve recently stumbled upon a great series of articles titled “Getting Func-ey” by Mat Fournier. At the time of me writing this short review, there’ve been four parts released already, while the fifth (and the final one) is still in progress (as the author claims).

Mat goes over the motivations & reasons to write functional Scala. The topics that are covered include basics of functional programming style, foundations of type systems, programming with effects and using typeclasses. Batteries included — all that reading comes with tons of examples, along with a handful of snippets comparing the code to the good, ol’ Haskell.

I definitely recommend that series to anybody, who’s looking for well-explained concepts of moderate to advanced functional programming, but found books on the topic too intimidating. On the other hand, even if you are already an advanced FP-warrior, reading through the series might be a good supplement to your knowledge so far.

Insights about Http4s Timeouts & cancelable IO by Michał M.

In a few of our projects we are leveraging the stack based on http4s and Cats Effect. Recently we have encountered quite an interesting situation. We knew that someone was calling our endpoints, but some of the logs and logic which should be happening were missing! It appeared that the reason were… Http4s Timeouts.

package org.http4s

package server

package middleware ... object Timeout { /** Transform the service to return a timeout response after the

* given duration if the service has not yet responded. If the

* timeout fires, the service’s response is canceled.

…

*/

def apply[...](...)

}

The service’s response is canceled! That was exactly the reason. If the logic would not be finished until configured timeout then the underneath effect is canceled. How does it work? If you are doing e.g. for comprehension based on a few IOs, it would skip the next IOs which should be executed. We were e.g. logging responses from external service in one of the IOs, so the logging got cancelled. As you may suspect, this external service once in a while was having longer response times, which resulted in timeouts on our side.

How does it work underneath? It uses Concurrent.race method:

/**

* Run two tasks concurrently and return the first to finish,

* either in success or error. The loser of the race is canceled.

…

*/

def race[A, B](fa: F[A], fb: F[B]): F[Either[A, B]] = ...

where first task is your logic, and second one a timer with appropriate response.

Most of the IOs are by default cancellable, but you can call uncancelable to avoid this behaviour.

How to split a bigger git project by Michał O.

It sometimes happens that you may need to split a bigger git project you work on into two separate repositories. There are various reasons for that, e.g. one being a conscious decision made upon project’s kick-off that you’d go with monolithic (but still modular) project first, deliver some MVP without much “operations” hassle and only then branch out. The other one may be changes in requirements over time that turn single highly focused application into an app doing more than one thing that could easily be split.

Sure, you can go kick-off new git repository and simply copy-paste code for the new application. This approach has one major drawback: it wipes out entire git history. So let’s try the other way around: duplicate entire repository and remove parts that are no longer necessary (e.g. in one giant commit). That would work, but will keep history for all the parts that have been removed too. Not bad, but is there a more elegant way?

There is a git spell for that (surprised?). It’s called subtree split and it works like a charm (checked!). Basically it goes through the git history and only keeps commits that are relevant to given directories subtree you want to extract. That way if you have separate module that you want to create new project from, just give it a try and you’ll get new and shiny repository with just the history that matters in this context.

Read more on it here!