axelson

axelson

Scenic Core Team

ElixirConf 2017 - Phoenix after 100000 lines - Renan Ranelli

Given phoenix’s rise in popularity, the internet is flooded with examples and “getting started” tutorials.

What happens when your phoenix app grows beyond the “trivial” examples we see in the wild? What are the good patterns you should adopt and what are the ones you should avoid?

In this talk I’m going to share the problems (and solutions!) we encountered while growing our 2+ year old phoenix app beyond 100,000 lines of code, while also migrating from server-side html to a full fledged SPA.

After this talk, the listener will be able to (hopefully) better access the trade-offs and impacts on using Phoenix for their next (hopefully big) project.

Audience: All

All talks are available in the Elixir Conf 2017 Talks List or via the elixirconf2017 tag

Showing Posts 1 to 8

JEG2

JEG2

Author of Designing Elixir Systems with OTP

This was a pretty good description of real world Phoenix. I enjoy hearing what worked and didn’t for other groups.

kylethebaker

kylethebaker

The long compilation was surprising to me. I haven’t ran into a problem with long compilations myself, though I do notice that any changes to my phoenix router causes several modules to recompile. The blog post he wrote about recompilations is an insightful read: http://milhouseonsoftware.com/2016/08/11/understanding-elixir-recompilation/

The solutions presented seem to be: avoid unnecessary imports/requires, use Module.concat if you are sure you can get away with (probably best avoided I would assume), and avoid cyclic dependencies. The first seems easy enough, the second seems like its best to avoid, and the third seems like it requires changing your logic. Are cyclical dependencies intrinsically bad, or are they only bad because of the effect they have on compile time? In other words, should I be going out of my way to avoid them even before compile time becomes an issue?

axelson

axelson OP

Scenic Core Team

I enjoyed seeing some of the problems that they came up against in such a large app. I definitely like how easy it is to create new types for Ecto, makes it very extensible. Wish he had some more information about how they manage that large a code base, module structure, file system structure, break down into separate library apps and umbrella applications.

josevalim

josevalim

Creator of Elixir

I would say the Module.concat is best left for libraries and frameworks. So if you are writing a library that relies heavily on meta-programming, you may want to have that in mind but not in your app. At the time the article was written, which is indeed excellent, we got some of those lessons and applied them to Ecto (Phoenix already did it).

It is also worth mentioning Elixir v1.6 will improve the compile-time tracking so hopefully we can keep ahead of most of the community when it comes to compilation times.

josevalim

josevalim

Creator of Elixir

I just finished the talk, I just want to clarify one more thing regarding the compilation. Renan mentioned that the Phoenix router takes a long time to compile but that’s likely not the case. The issue is that a lot of his application likely depends on the router and that holds everything else back. To some extent this is Phoenix’s fault since controllers and views import the router and that sets up a compile time dependency. I have pinged Renan to confirm this and opened up an issue on Phoenix’s issues tracker.

wojtekmach

wojtekmach

Hex Core Team

Just wanted to add that It’s pretty easy to introduce a lot of module dependencies to the router via plugs, e.g.:

# router.ex
plug MyApp.CurrentUser

# current_user.ex
def call(conn, _) do
  Users.get(...)
end

this introduces a compile-time dependency between the Router and MyApp.CurrentUser
And then if the Users/User modules (or any of their runtime/compile dependencies) change the router will need to be recompiled and thus all controllers & views. Although it’s a hacky solution, having one Module.concat in critical place (e.g. the one plug that reaches out to schemas) can save a lot of recompilations.

josevalim

josevalim

Creator of Elixir

I would say that’s fine. The real issue is that many modules have a compile time dependency on the router and that could be solved if we aliases the router helpers instead of importing them.

kelvinst

kelvinst

IMHO cyclical deps are intrinsically bad most of the times, since when two modules depend from each other, they are tightly coupled (one does not work without the other and vice-versa).

But (and that’s a big but) sometimes you just want to separate tightly coupled logic from a module in two modules for organisation purposes, and I think that’s OK, but I would try to extract a module which does not depend on its source module.

— All posts loaded —

Where Next? Top

Trending in Talks Top

Other Trending Topics Top

budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
budgie
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with. But I don’t use it anymore. Serverless was the promis...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews