Elixir:主管、GenServer 和应用程序之间的区别
Elixir: Difference between Supervisor, GenServer and Application
我正在练习这个例子。
https://github.com/kwmiebach/how-to-elixir-supervisor
我按照说明了解了它的工作原理,但我无法理解 Supervisor、GenServer 和 Application 之间究竟有何不同。
谁能解释一下这 3 个有什么不同以及应该在什么时候使用它们?
首先,这些都是 "OTP Design Principles"(并由标准库支持),它们都是基本 Erlang 原语(如进程)之上的包装器(或更准确地说,是抽象)。这意味着它们 不是 在 Erlang(因此 Elixir)中编程的唯一方法,但它们由社区共享并得到数十年经过实战考验的现实世界系统的支持。所以你也应该使用它们。
GenServer
通常被认为是使用 Elixir 实现的应用程序的基本 运行time 构建块。尽管实际上它是低级别 Erlang Process 原语的包装器,但是 GenServer
提供了许多高级功能,例如在标准接口中进行调试和跟踪。基本上,您通常会使用(许多)GenServer
来管理应用程序中的状态和 "do actual work"。
Supervisor
, as the documentation suggests:
A supervisor is a process which supervises other processes, which we refer to as child processes. Supervisors are used to build a hierarchical process structure called a supervision tree.
所以在某种意义上,它 "manages" GenServer
s,还有其他 Supervisor
s(和其他 Erlang Process 抽象,如果它们实现了适当的接口)。您通常不会在 Supervisor
模块中放置任何自定义逻辑,部分原因是它们的作用非常集中——仅管理子进程的生命周期。而且还使其不易出错(由您的更改引入)。
换句话说,Supervisor
不会为您的应用程序做任何实际的 "work",它只是用于 "layout" 系统架构。
与其他人相比,Application
不一定 "runtime concern",as the Erlang documentation suggests:
... make the code into an application, that is, a component that can be started and stopped as a unit, and which can also be reused in other systems.
所以 Application
实际上是关于将东西捆绑到 "unit" 中,而真实的系统通常由许多这样的单元组成 - 例如每当你 运行 一些 Elixir 代码时,有还有一个 "elixir" Application
,其中 运行 有几个进程,例如 elixir_code_server
:
更重要的是,Application
是 OTP 设计原则中共享(重用)代码的方式。当你定义一个应用程序时,它可以有一个"root supervisor",它与应用程序一起启动。或者它也可以只有功能代码,根本没有 运行ning 任何进程,比如 a JSON library。无论哪种方式,要在不同系统之间重用代码,都需要将它们打包成 Application
s.
最后,我建议读一读:https://ferd.ca/the-zen-of-erlang.html 它解释了(至少对我而言)我们如何从基本 (Erlang) 流程发展到监管者(和监管树),以及一些一些 OTP 应用程序。 (以及我们应该如何在 BEAM 中进行编程)
我正在练习这个例子。
https://github.com/kwmiebach/how-to-elixir-supervisor
我按照说明了解了它的工作原理,但我无法理解 Supervisor、GenServer 和 Application 之间究竟有何不同。
谁能解释一下这 3 个有什么不同以及应该在什么时候使用它们?
首先,这些都是 "OTP Design Principles"(并由标准库支持),它们都是基本 Erlang 原语(如进程)之上的包装器(或更准确地说,是抽象)。这意味着它们 不是 在 Erlang(因此 Elixir)中编程的唯一方法,但它们由社区共享并得到数十年经过实战考验的现实世界系统的支持。所以你也应该使用它们。
GenServer
通常被认为是使用 Elixir 实现的应用程序的基本 运行time 构建块。尽管实际上它是低级别 Erlang Process 原语的包装器,但是 GenServer
提供了许多高级功能,例如在标准接口中进行调试和跟踪。基本上,您通常会使用(许多)GenServer
来管理应用程序中的状态和 "do actual work"。
Supervisor
, as the documentation suggests:
A supervisor is a process which supervises other processes, which we refer to as child processes. Supervisors are used to build a hierarchical process structure called a supervision tree.
所以在某种意义上,它 "manages" GenServer
s,还有其他 Supervisor
s(和其他 Erlang Process 抽象,如果它们实现了适当的接口)。您通常不会在 Supervisor
模块中放置任何自定义逻辑,部分原因是它们的作用非常集中——仅管理子进程的生命周期。而且还使其不易出错(由您的更改引入)。
换句话说,Supervisor
不会为您的应用程序做任何实际的 "work",它只是用于 "layout" 系统架构。
与其他人相比,Application
不一定 "runtime concern",as the Erlang documentation suggests:
... make the code into an application, that is, a component that can be started and stopped as a unit, and which can also be reused in other systems.
所以 Application
实际上是关于将东西捆绑到 "unit" 中,而真实的系统通常由许多这样的单元组成 - 例如每当你 运行 一些 Elixir 代码时,有还有一个 "elixir" Application
,其中 运行 有几个进程,例如 elixir_code_server
:
更重要的是,Application
是 OTP 设计原则中共享(重用)代码的方式。当你定义一个应用程序时,它可以有一个"root supervisor",它与应用程序一起启动。或者它也可以只有功能代码,根本没有 运行ning 任何进程,比如 a JSON library。无论哪种方式,要在不同系统之间重用代码,都需要将它们打包成 Application
s.
最后,我建议读一读:https://ferd.ca/the-zen-of-erlang.html 它解释了(至少对我而言)我们如何从基本 (Erlang) 流程发展到监管者(和监管树),以及一些一些 OTP 应用程序。 (以及我们应该如何在 BEAM 中进行编程)