summaryrefslogtreecommitdiff
path: root/CHANGELOG.md
diff options
context:
space:
mode:
authorAndrea Leopardi <an.leopardi@gmail.com>2022-06-02 13:08:34 +0200
committerGitHub <noreply@github.com>2022-06-02 13:08:34 +0200
commit1f1f43d23a2993aac95699409c76b229bac65985 (patch)
tree0a10fad33a09ca8188bbf25aff600b41d9aee673 /CHANGELOG.md
parent284ccd17c48021a0f2b07bdcbe1a2ba70cdc7339 (diff)
downloadelixir-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.md75
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