5 votes

différence entre les applications d'élixir de travailleur et de superviseur

Je suis tout nouveau sur elixir/phoenix. Je travaille sur une application créée précédemment qui a plusieurs dépôts et aujourd'hui je vois un exemple qui me fait me demander ce que signifie cette configuration.

Je pense que je ne sais pas comment chercher, c'est la raison pour laquelle je ne trouve pas la bonne réponse dans la documentation.

d'abord l'application sur laquelle je travaille a quelque chose comme

defmodule RestApi do
  use Application

  def start(_type, _args) do
    import Supervisor.Spec, warn: false

    children = [
      supervisor(RestApi.Endpoint, []),
      supervisor(RestApi.Repo, []),]),
      supervisor(RestApi.OtherRepo, []),]),
    ]

    opts = [strategy: :one_for_one, name: RestApi.Supervisor]
    Supervisor.start_link(children, opts)
  end

  def config_change(changed, _new, removed) do
    RestApi.Endpoint.config_change(changed, removed)
    :ok
  end
end

ils utilisent la fonction Superviseur.Spec.superviseur/3 pour tout démarrer/gérer

J'ai ensuite trouvé un exemple

defmodule RestApi do
  use Application

  def start(_type, _args) do
    import Supervisor.Spec, warn: false

    children = [
      supervisor(RestApi.Endpoint, []),
      worker(RestApi.Repo, []),
    ]

    opts = [strategy: :one_for_one, name: RestApi.Supervisor]
    Supervisor.start_link(children, opts)
  end

  def config_change(changed, _new, removed) do
    RestApi.Endpoint.config_change(changed, removed)
    :ok
  end
end

dans le exemple ils utilisent Superviseur.Spec.worker/3 pour démarrer/gérer le repo

Quelle est la différence entre les deux ? Je veux dire comment cela affecte l'application (performance, consommation de mémoire, etc).

9voto

mudasobwa Points 5530

Imaginez que le superviseur est une branche de l'arbre de supervision, tandis que le travailleur est une feuille.

Chaque supervisor es un worker alors que chaque worker es un supervisor . Bien que le supervisor dispose d'un ensemble de fonctions spécifiquement dédiées à la gestion des processus enfants, il a en fait un impact très faible sur la productivité par rapport à la fonction générique gen_server . Cet extrait de Principes de conception de l'ANP explique ce que supervisor est censé être pour :

Un superviseur est responsable du démarrage, de l'arrêt et de la surveillance de ses processus enfants. L'idée de base d'un superviseur est qu'il doit maintenir ses processus enfants en vie en les redémarrant si nécessaire.
Les processus enfants à démarrer et à surveiller sont spécifiés par une liste de spécifications enfants. Les processus enfants sont lancés dans l'ordre spécifié par cette liste, et terminés dans l'ordre inverse.

En outre, c'est "le worker ."

Cela dit, il existe une règle empirique facile à adopter : quand le processus gère des processus enfants, c'est une supervisor il s'agit d'un worker autrement.

Dans l'exemple mentionné :

children = [
  supervisor(RestApi.Endpoint, []),
  worker(RestApi.Repo, []),
]

RestApi.Endpoint gère les processus des enfants, et RestApi.Repo ne le fait pas. A part ça, les deux sont tout simplement bons gen_server s.

2voto

bitwalker Points 7588

Vous utilisez supervisor pour lancer des processus qui sont des superviseurs, et worker pour lancer des travailleurs (en fait, tout ce qui n'est pas un superviseur). Vous trouverez plus d'informations à ce sujet dans la documentation des modules Supervisor et Supervisor.Spec.

Il semble que soit le type de processus a changé entre les versions, ou l'un de ces exemples a un bug, mais je crois que c'est censé être un processus de travail, mais je voudrais vérifier les docs Ecto.

Quant à la façon dont cela affecte l'application, il n'y a pas de différence significative autre que la documentation du type de processus de l'enfant - elle est en fait facultative en Erlang. Les superviseurs gèrent leur propre ensemble de processus enfants, formant un arbre de superviseurs. Vous l'utilisez pour isoler les effets des pannes sur les sous-branches de cet arbre afin que les parties non liées de l'application puissent continuer à fonctionner pendant que la branche défaillante est redémarrée par son superviseur. C'est la source de la tolérance aux pannes dans le langage et un élément fondamental de l'OTP.

Les workers sont de loin le type de processus le plus courant, ils ne gèrent pas de processus enfants, et sont conçus pour se planter et être redémarrés par leur superviseur lorsque les choses tournent mal, l'idée étant de repartir d'un état propre et connu. Un trop grand nombre d'échecs provoque le plantage du superviseur parent, qui est à son tour redémarré par son superviseur - si ce phénomène atteint le superviseur de niveau supérieur de votre application, celle-ci se plantera.

J'espère que cela vous aidera :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X