Elixir Blog Posts

blog-posts
wiki
stickies

#387

GenServer’s handle_call/3, handle_cast/2, and handle_info/2 natively support sliding timeouts. You don’t need to write any custom code.

handle_call/3

Returning {:reply, reply, new_state, timeout} is similar to {:reply, reply, new_state} except handle_info(:timeout, new_state) will be called after timeout milliseconds if no messages are received.

handle_cast/2

Returning {:noreply, new_state, timeout} is similar to {:noreply, new_state} except handle_info(:timeout, new_state) will be called after timeout milliseconds if no messages are received.

handle_info/2

Return values are the same as handle_cast/2 .


#388

The problem with those timeouts (in my use case) is that any message to the GenServer will cancel them. However, in my use case we wanted our timer to slide or timeout based on messages from a specific process.


#389

http://www.jackmarchant.com/articles/add-docker-to-elixir-phoenix-projects


#390

This is a blog post I wrote last year that dives into implementing protocols and writing an Ecto.Type


#391

Errors are not exceptional

This is a blog post I’ve been intending to write for ages.

TL;DR bad input is not exceptional. Only use exceptions for truly exceptional cases. Try OK.


#392

Debugging your Phoenix, Elixir and Rails applications inside Docker containers A blog post on how to get the REPL working inside docker containers.


#393

Why did José Valim create Elixir?
A blog post I wrote after listening again to an old podcast episode. It was possibly the first mention to Elixir in a podcast.


#394

I followed up on this post about generating guitar chord voicings with two new posts. The first calculates all possible* fingerings for a given chord voicing, and the second uses a modified Levenshtein distance algorithm to compute how difficult it is to transition from one chord to another.

With those two pieces in place, I’ve been able to do some cool stuff like generating entire chord progressions that flow well in terms of voice leading, and playability. For example, here’s a ii-V-I in C I generated by just giving it the starting chord and fingerings:

  9 │││●││ Cmaj7
    ├┼┼┼┼┤
    │●●│││
    ├┼┼┼┼┤
    ││││││
    ├┼┼┼┼┤
    ││││●│
     2314 

  7 │││●││ Dm7
    ├┼┼┼┼┤
    │●││││
    ├┼┼┼┼┤
    ││││││
    ├┼┼┼┼┤
    ││●│●│
     2314 

  7 │││●││ G7
    ├┼┼┼┼┤
    │●││●│
    ├┼┼┼┼┤
    ││●│││
    ├┼┼┼┼┤
    ││││││
     2413 

  5 │││●││ Cmaj7
    ├┼┼┼┼┤
    ││││││
    ├┼┼┼┼┤
    │●││││
    ├┼┼┼┼┤
    ││││●│
    ├┼┼┼┼┤
    ││●│││
     2413 

Some of these chords are a little wonky for various reasons, but I’ve got more ideas to improve the project. If you can’t tell, I’m pretty excited about this.

  • For some values of “possible”.

#395

#396

#397

Where did you learn that import copies the function bodies? I thought it just resolved them at compile time and wrote the fully qualified invocation into the resulting BEAM file.

Oh wait: I just realized you’re not the author of the blog. Sorry!


#398

Where can an Elixir beginner ask for help? – Adolfo Neto – Medium https://buff.ly/2pqzSl6


#399

https://www.jackmarchant.com/articles/using-protocols-to-decouple-implementation-details


#400

I have blogged about configuration & Elixir here:

that builds upon some discussions we’ve been having here, most notably:




#401

I think your post also assumes that the build happens on the production or production-like server that also contains the secrets. Am I reading it right?


#402

No, hmm not at all. You can use distillery 2.0 and read them at runtime as I show a the end of post.


#403

Nice! Ya I misread that! Guess I’m so used to there being caveats but ya, Distillery 2.0 with mix config providers is really nice. Thanks for the great post. I might have to redo how I have my app configured now with this in mind. I’m still using the REPLACE_OS_VARS style.

I think this is where I got tripped up:

Since config providers only execute pre-boot, you must restart the release to pick up configuration changes. If using hot upgrades, the config providers will run during the upgrade, and so will pick up any config changes at that time. https://hexdocs.pm/distillery/extensibility/config_providers.html

So, even though it’s technically read at runtime, it might still feel like compile-time since the app has to reboot to get changed environment variables. (don’t actually have to recompile the app-- just reboot).


#404

Yet this problem is completely addressed in more recent versions. Now you can tell Plug.Parsers how to read the body or tell it to not read it at all in certain cases. The PR was a 2LOC change on each existing parser. No software is perfect, they will all have limitations that need to be addressed. It is amazing what can be achieved when folks approach a weird behaviour as an opportunity to improve things rather than point fingers.

I also want to point out that even a data structure of the request would be bound to “hardly a good example of composa-able”. All that is necessary is for a “middleware” upstream to rewrite a request in a way it is incompatible for downstream. For example, a middleware may discard the request body to save memory (think large file uploads). If another middleware expects the request body to always be there, it will now break. Alternatively you can say it is not possible to discard the request body but then you are opening your application up to easier to pull attack vectors.

So those decisions are not tied to the architectural choice of the project but rather a design decision which could have gone both ways. Plug aims to put stronger emphasis over when the request is read and the response is sent. I would rather read the request body once and make sure to derive all of the properties I need from it in a single place rather than passing the request body around the whole stack in the off chance something else need it.


#405

I had been following the PR and am pleased that it is now fixed.

Never tried to imply I was expecting that, I personally spent quite a long time in Plug source looking for a solution.

I can’t quite believe I’m saying this again, but this is really not my intention.

In functional programming it can be valuable to have as much code as possible pure.
I also recognise that in some cases this goal of purity is not practical.
Plug has made very sensible choices here for it’s model.
However reading and writing a body in plug just is impure in some cases.

My own experiments (Raxx) was never meant to be more than an attempt to see if I could increase the amount of the interface that was pure.
In the end I came up with a solution that I quite like.

I couldn’t quickly google what pull attack vectors are, so I’m not sure what is being said here.

I would just say that Raxx has evolved quite a lot from it’s Rack based inspiration. Arbitrarily large request bodies will not just gut pushed into a data structure .


#406

Hopefully nobody expects software to be perfect. However, when a small and fixable issue is taken as an indicative of a bigger problem, when it is not, the lasting impression is that we don’t have a lot of space for making mistakes (exactly because small mistakes will be taken as an indicative of a bigger problem, when they are not, so we need to make sure everything is fail proof).

Reading and writing a body is always impure. You can’t escape from the real world. The question is how and when you handle it. If you choose to not expose it to your users at all, with a completely pure data driven approach of the request and response with no callbacks, then you are removing runtime capabilities from your users in terms of connection and memory management.

A callback based approach can be made of pure callbacks but the model is still impure and some of the callbacks are likely dictated by the impure nature of the model. For example, in a GenServer you still have GenServer.reply/2, which is an impure operation, because otherwise certain patterns are impossible to implement.

I am not saying one approach is better than the other. My point is that because the domain modelled here is inherently impure, concessions have to be made at some point (in Erlang/Elixir at least).

Attacks like slowloris are easier to pull off when the body is being kept in memory, especially because the body size limit is typically way higher than the headers one.