diff options
author | Andrea Leopardi <an.leopardi@gmail.com> | 2022-06-02 13:08:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-02 13:08:34 +0200 |
commit | 1f1f43d23a2993aac95699409c76b229bac65985 (patch) | |
tree | 0a10fad33a09ca8188bbf25aff600b41d9aee673 /CHANGELOG.md | |
parent | 284ccd17c48021a0f2b07bdcbe1a2ba70cdc7339 (diff) | |
download | elixir-1f1f43d23a2993aac95699409c76b229bac65985.tar.gz |
Add PartitionSupervisor section to the changelog (#11892)
Co-authored-by: José Valim <jose.valim@dashbit.co>
Diffstat (limited to 'CHANGELOG.md')
-rw-r--r-- | CHANGELOG.md | 75 |
1 files changed, 73 insertions, 2 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b799e205..d4166b000 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,81 @@ # Changelog for Elixir v1.14 -Elixir v1.14 requires Erlang/OTP 23+. +Elixir v1.14 requires Erlang/OTP 23+ with a small batch of new features +and the usual enhancements and bug fixes to Elixir and its standard library. +We cover the most notable changes next. ## PartitionSupervisor -TODO. +`PartitionSupervisor` is a new module that implements a new supervisor type. The +partition supervisor is designed to help with situations where you have a single +supervised process that becomes a bottleneck. If that process's state can be +easily partitioned, then you can use `PartitionSupervisor` to supervise multiple +isolated copies of that process running concurrently, each assigned its own +partition. + +For example, imagine you have a `ErrorReporter` process that you use to report +errors to a monitoring service. + +```elixir +# Application supervisor: +children = [ + # ..., + ErrorReporter +] + +Supervisor.start_link(children, strategy: :one_for_one) +``` + +As the concurrency of your application goes up, the `ErrorReporter` process +might receive requests from many other processes and eventually become a +bottleneck. In a case like this, it could help to spin up multiple copies of the +`ErrorReporter` process under a `PartitionSupervisor`. + +```elixir +# Application supervisor +children = [ + {PartitionSupervisor, child_spec: ErrorReporter, name: Reporters} +] +``` + +The `PartitionSupervisor` will spin up a number of processes equal to +`System.schedulers_online()` by default (most often one per core). Now, when +routing requests to `ErrorReporter` processes we can use a `:via` tuple and +route the requests through the partition supervisor. + +```elixir +partitioning_key = self() +ErrorReporter.report({:via, PartitionSupervisor, {Reporters, partitioning_key}}, error) +``` + +Using `self()` as the partitioning key here means that the same process will +always report errors to the same `ErrorReporter` process, ensuring a form of +back-pressure. You can use any term as the partitioning key. + +### A Common Example + +A common and practical example of a good use case for `PartitionSupervisor` is +partitioning something like a `Task.Supervisor`. With many tasks under it, a +task supervisor can be a bottleneck. Instead of starting a single +`Task.Supervisor` for a set of tasks, you can start multiple ones: + +```elixir +children = [ + {PartitionSupervisor, child_spec: Task.Supervisor, name: MyApp.TaskSupervisors} +] + +Supervisor.start_link(children, strategy: :one_for_one) +``` + +Now you start tasks on the task supervisor for the right partition. For +instance, you can partition by PID, like in the previous example: + +```elixir +Task.Supervisor.async( + {:via, PartitionSupervisor, {MyApp.TaskSupervisors, self()}}, + fn -> :do_some_work end +) +``` ## Improved errors on binaries and evaluation |