-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Revamp Mix & OTP guides #14637
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Revamp Mix & OTP guides #14637
Conversation
This is a large one and it will be inconvenient to review on GitHub. My suggestion is to clone it locally, make a changes, and then send a PR targetting this branch. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates. Some feedback on typos and unclear sentences =)
@@ -47,7 +42,7 @@ iex> Agent.stop(agent) | |||
:ok | |||
``` | |||
|
|||
We started an agent with an initial state of an empty list. We updated the agent's state, adding our new item to the head of the list. The second argument of `Agent.update/3` is a function that takes the agent's current state as input and returns its desired new state. Finally, we retrieved the whole list. The second argument of `Agent.get/3` is a function that takes the state as input and returns the value that `Agent.get/3` itself will return. Once we are done with the agent, we can call `Agent.stop/3` to terminate the agent process. | |||
We started an agent with an initial state of an empty list. The `start_link/1` function returned the `:ok` tuple with a process identifier (PID) of the agent. We will use this PID for all further interactions. We then updated the agent's state, adding our new item to the head of the list. The second argument of `Agent.update/3` is a function that takes the agent's current state as input and returns its desired new state. Finally, we retrieved the whole list. The second argument of `Agent.get/3` is a function that takes the state as input and returns the value that `Agent.get/3` itself will return. Once we are done with the agent, we can call `Agent.stop/3` to terminate the agent process. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that we now explain the child_spec
concept in a later guide, which is great. I can't think of the right wording currently, but I think we should hint at it a small bit here to make it clear that start_link/1
is more than just a convention, but something that Elixir expects to be defined so that it knows how to start this agent.
Tried to use generic wording there to avoid explaining supervisors and child specs, but the important bit is that start_link/1
should exist and should be called start_link/1
and its more than just a naming convention.
Co-authored-by: Matt Enlow <matt@novaugust.net>
Co-authored-by: Zach Daniel <zach@zachdaniel.dev>
Co-authored-by: Matt Enlow <matt@novaugust.net> Co-authored-by: Zach Daniel <zach@zachdaniel.dev>
deps_path: "../../deps", | ||
lockfile: "../../mix.lock", | ||
The pattern of keeping multiple applications in the same repository is known as |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Umbrella projects are a convenience to help you organize and manage multiple applications.
The pattern of keeping multiple applications in the same repository is known as monorepo. Umbrella projects maximize
I think there is a lot of room for people to misinterpret these and still choose umbrellas despite, IMO, almost certainly not needing them. It doesn't, for example, explain why you may or may not want to have multiple applications. I think it is really worth pointing out here what some "bad" reasons for choosing umbrellas are. i.e:
- you don't need them to organize complex or large applications
- you don't need them for complex deployments where you disable parts of your application
- you don't need them to run multiple "services", like web endpoints, in a single application.
I would consider that a normal Elixir application structure, not an umbrella at all, can run as what people think of as a "monorepo" with no special requirements at all. Multiple supervision trees, multiple ingress, multiple "areas" of an application etc.
At a minimum I think we should say something that implies that "if you are not certain you need an umbrella, then you very likely do not".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added some docs on collapsing umbrellas into one but I already think the current docs have enough disclaimers around umbrellas. We should also be mindful of "the consultant problem", where we frequently hear about things that are not working, because if they were working, people would not reach out to us. I know both of us are consultants but I am not saying it applies to our jobs exclusively, that's just how the problem was named to me some time ago, and I believe it applies equally to forums and other community spaces.
In particular, umbrellas did have an issue in that they did allow cross dependencies between modules, but those have been tackled more than 5 years ago. The other challenge people encounter are often related to third-party tooling (for example, Mix tasks not working with umbrellas), but those should be fixed, otherwise we end-up with a self fulfilling prophecy that umbrellas do work well because of the tooling, so fewer people use them, and then there are even fewer incentives to fix them.
It is also important to keep in mind that the incentives around umbrellas may change in the future too:
-
Elixir may not perform type inference within the same application, but should it perform across siblings in an umbrella?
-
Erlang has discussed over several years doing optimization across modules in the same application, if that ever ships, how would that impact umbrellas?
And we need to have keep them well supported if we want to have those discussions in the future.
Co-authored-by: Rodolfo Carvalho <rhcarvalho@gmail.com>
@@ -170,81 +170,84 @@ As the name says, doctest is documentation first and a test later. Their goal is | |||
As we are now able to parse commands, we can finally start implementing the logic that runs the commands. Let's add a stub definition for this function for now: | |||
|
|||
```elixir | |||
defmodule KVServer.Command do | |||
defmodule KV.Command do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not part of this change, but the with 2 lines above also renders as code, but also a header in exdoc like the other screenshot above.
Co-authored-by: Steffen Deusch <steffen@deusch.me> Co-authored-by: Gary Rennie <gazler@gmail.com>
Co-authored-by: Steffen Deusch <steffen@deusch.me> Co-authored-by: Gary Rennie <gazler@gmail.com>
Co-authored-by: Steffen Deusch <steffen@deusch.me>
💚 💙 💜 💛 ❤️ |
In a nutshell:
Registry
:global
and talk about more relevant problems to today's developers, such as naming registries and node discoveryDownsides: