Les événements sont-ils utilisés uniquement pour la programmation graphique?


57

Les événements sont-ils utilisés uniquement pour la programmation graphique?

Comment gérez-vous dans la programmation backend normale quand quelque chose arrive à cet autre chose?


6
À propos, Event Source est un concept totalement orthogonal à la programmation par événement. Le concept de base de Event Sourcing est que vous stockez des "événements" ou des "modifications" sur votre système, au lieu de stocker "l'état" de votre système. Par exemple, vous pouvez modéliser votre compte bancaire comme suit: a) votre solde (ÉTAT) ou b) une série de transactions (EVENTSOURCE).
ArTs

4
En fonction de l'utilisation, un "événement" est généralement une forme de rappel enveloppée de sucre. Les rappels s'utilisent partout - si cela vous intéresse, c'est probablement un bon mot clé pour lancer une recherche.
J ...

10
Je tiens également à souligner que même si vous optez pour un microcontrôleur de niveau aussi bas, vous constaterez que les interruptions matérielles sont une fonctionnalité utile et essentielle au débat. Idéal pour les systèmes de contrôle ou IO de base comme une cafetière. Ces interruptions matérielles ne sont pas vraiment différentes des événements.
Dan

Nan! Exemple pratique: événements Nodejs
sampathsris le

2
Êtes-vous sur Windows? Consultez l'observateur d'événements. S'amuser.
Marc.2377

Réponses:


106

Nan. Ils sont vraiment pratiques pour implémenter des observateurs et s’assurer que les classes sont fermées à la modification.

Disons que nous avons une méthode qui enregistre de nouveaux utilisateurs.

public void Register(user) {
    db.Save(user);
}

Ensuite, quelqu'un décide qu'un e-mail doit être envoyé. Nous pourrions faire ceci:

public void Register(user) {
    db.Save(user);
    emailClient.Send(new RegistrationEmail(user));
}

Mais nous venons de modifier une classe censée être fermée à la modification. Probablement bien pour ce pseudo-code simple, mais probablement le chemin de la folie dans le code de production. Combien de temps a-t-il fallu jusqu'à 30 lignes de code pour que cette méthode soit à peine liée à l'objectif initial de création d'un nouvel utilisateur?

Il est bien plus agréable de laisser la classe utiliser ses fonctionnalités essentielles et de créer un événement indiquant à tous les utilisateurs qui sont à l'écoute qu'un utilisateur était enregistré et qu'ils peuvent prendre les mesures nécessaires (telles que l'envoi d'un courrier électronique).

public void Register(user) {
    db.Save(user);

    RaiseUserRegisteredEvent(user);
}

Cela garde notre code propre et flexible. L'un des aspects souvent négligés de la programmation orientée objet est que les classes s'envoient des messages . Les événements sont ces messages.


37
Je lis ceci et pense à notre code "créer une réservation" et je pleure pendant un moment et je cherche un meilleur endroit: '(
sara

1
+1, bonne réponse. Juste une question tangentielle (cela me gênait un peu): y a-t-il une raison particulière pour que vous ayez commencé vos noms de méthode (Register, Save and Send) en majuscules? Bien sûr, cela n’affecte pas l’utilité de cette réponse.
Pedro

14
@Hamsteriffic Je suis principalement un développeur C # et c'est la convention généralement acceptée. Aucune autre raison.
RubberDuck

6
@Hamsterifficas un ajout, ce que vous appelez lowerCase mais qui contient une majuscule au milieu est souvent appelé camelCase, car il a des bosses au milieu. Cela le distingue de snake_case, où les mots minuscules sont séparés par des traits de soulignement, ce qui est familier pour Python et la plupart des langages de shell, pour n'en nommer que quelques-uns.
Aaron

5
Les événements sont un type de ces messages, je dirais. Les appels de méthode doivent également être considérés comme un message en train de passer.
jpmc26

53

Nan.

Un exemple classique d'événements utilisés dans une logique non graphique est la base de données.

Les déclencheurs sont un code qui est exécuté lorsqu'un événement donné se produit (INSERT, DELETE, etc.). Cela ressemble à un événement pour moi.

Ceci est la définition de l'événement par Wikipedia:

En informatique, un événement est une action ou un événement reconnu par un logiciel qui peut être traité par le logiciel. Les événements informatiques peuvent être générés ou déclenchés par le système, par l'utilisateur ou d'une autre manière. En règle générale, les événements sont gérés de manière synchrone avec le flux de programmes, c’est-à-dire que le logiciel peut avoir un ou plusieurs emplacements dédiés où les événements sont gérés, souvent une boucle d’événements. Une source d’événements inclut l’utilisateur, qui peut interagir avec le logiciel, par exemple en appuyant sur les touches du clavier. Une autre source est un périphérique matériel tel qu'une minuterie. Le logiciel peut également déclencher son propre ensemble d’événements dans la boucle d’événements, par exemple pour communiquer l’achèvement d’une tâche. Les logiciels qui changent de comportement en réponse à des événements sont dits événementiels, souvent dans le but d'être interactifs.

Tous les événements ne sont pas générés par l'utilisateur. Certains sont générés par une minuterie, comme une crontab, par une base de données INSERT, comme je l’ai déjà mentionné.

La définition indique également que certains programmes ou systèmes sont "pilotés par les événements, souvent dans un but d'interaction" , d'où l'on peut déduire que le but ou l'utilité des événements ne sont pas uniquement, mais souvent, de fournir une interactivité (comme des interfaces graphiques). mais pas nécessairement les interfaces graphiques, car les programmes CLI peuvent aussi être interactifs).


2
J'y pense toujours lorsque j'entends parler des déclencheurs de base de données: thecodelesscode.com/case/42
Almo

En tant qu'ex-administrateur de base de données, à présent, je grince des dents chaque fois que j'entends parler d'utiliser des déclencheurs sans tenir compte des performances plus larges de la base de données.
Trois logique de valeur

27

La programmation par événement est en fait également utilisée pour une programmation serveur hautement performante.

Avec une charge de travail typique du serveur, une grande partie du temps nécessaire pour traiter un résultat provient en réalité des E / S. Par exemple, l'extraction de données d'un disque dur (7 200 tr / min) peut prendre jusqu'à 8,3 ms. Pour un processeur GHz moderne, cela équivaudrait à environ 1 million de cycles d'horloge. Si un processeur attendait les données à chaque fois (sans rien faire), nous perdrions BEAUCOUP de cycles d'horloge.

Les techniques de programmation traditionnelles résolvent ce problème en introduisant plusieurs threads . Le processeur essaie d'exécuter des centaines de threads simultanément. Cependant, le problème de ce modèle est que, chaque fois qu’un processeur change de thread, il faut des centaines de cycles d’horloge pour changer de contexte . Un changement de contexte survient lorsque la CPU copie la mémoire locale du thread dans les registres de la CPU et stocke également le registre / l'état de l'ancien thread dans la RAM.

De plus, chaque thread doit utiliser une certaine quantité de mémoire pour stocker son état.

Aujourd'hui, il y a eu une poussée pour les serveurs qui ont un seul thread, qui tourne en boucle. Ensuite, des tâches sont placées sur une pompe de messages , qui agit comme une file d'attente pour un seul thread (un peu comme sur un thread d'interface utilisateur). Au lieu d'attendre la fin du travail, la CPU définit un événement de rappel, par exemple pour accéder à un disque dur. Ce qui réduit le changement de contexte.

Le meilleur exemple d'un tel serveur est Node.js , qui a démontré sa capacité à gérer 1 million de connexions simultanées avec un matériel modeste, alors qu'un serveur Java / Tomcat aurait du mal à atteindre quelques milliers de personnes.


2
"Le matériel modeste" est un peu trompeur. Vous aurez besoin de 8 Go + pour Node, en plus de tout ce que le système d'exploitation utilise. Et si vous avez assez de mémoire, Tomcat peut facilement gérer quelques milliers de connexions. Certes, il y a une grande différence, mais ce n'est pas 1000x.
Paul Draper

@PaulDraper non, ce n'est pas possible. Et non ce n'est pas le cas. Vous avez besoin de 8 Go + pour seulement la pile de 8 000 threads. C'est la grande différence.
ArTs

3
@PaulDraper en plus de 8 Go est très modeste par rapport aux normes du serveur. J'ai travaillé sur des machines avec 128 Go de RAM et celles-ci ne sont même pas complètement chargées. Les bâtons de bélier coûtent plus cher que votre machine entière.
ArTs

cela dépend de la taille de votre pile. Par défaut, Oracle / OpenJDK est défini sur 1 Mo pour la plupart des plates-formes 64 bits et 512 Ko pour 32 bits. Si vous prenez juste les valeurs par défaut, vous aurez raison. Mais les paramètres par défaut ne vous conduisent pas aux connexions de nœud 1M;) Quoi qu'il en soit, 128K est suffisant; vous pouvez vous en tirer avec encore moins. Ce serait 1 Go d'espace de pile pour 8000 threads.
Paul Draper

6
Vous vous trompez. Même avec la taille de pile par défaut, vous n'avez besoin que de 8 Go de mémoire virtuelle . La mémoire est engagée à la volée au besoin. En règle générale, il vous suffit d' une seule page par pile, à moins que vous êtes en train de l' aide de la mémoire supplémentaire. Et dans la pratique, la plupart des threads d’un tel système n’ont que ces piles (en général) de 64 Ko. L'utilisation de la mémoire virtuelle est un gros problème sur un système d'exploitation 32 bits, mais pas autant sur un système 64 bits. Vous rencontrez beaucoup plus tôt d'autres limites, comme l'épuisement des ports TCP, par exemple :) Et où pensez-vous que ces "pseudo-piles" de nœuds sont stockées? C'est vrai, sur le tas.
Luaan

10

Les événements sont également très utilisés dans la programmation réseau (par exemple Nginx) pour éviter les boucles d’attente coûteuses et fournir une interface propre pour savoir exactement quand une opération donnée est disponible (E / S, données urgentes, etc.). C'est aussi une solution au problème C10k .

L'idée de base est de fournir au système d'exploitation un ensemble de sockets (c'est-à-dire des connexions réseau) pour surveiller les événements, tous ou tout simplement ceux qui vous intéressent particulièrement (données disponibles pour la lecture, par exemple); lorsqu'une telle activité est détectée par le système d'exploitation sur l'un des sockets de la liste, vous recevez une notification de l'événement que vous recherchiez par l'API, que vous devrez ensuite classer d'où elle vient et agir en conséquence. .

À présent, il s’agit d’une vue abstraite de bas niveau, qui est en outre difficile à mettre à l’échelle. Cependant, de nombreux frameworks de niveau supérieur traitent de cela de manière multiplateforme même: Twisted pour Python, Boost.Asio pour C ++ ou libevent pour C me viennent à l’esprit.


+1 "boucles d’attente coûteuses": en d’autres termes, il est utile dans tous les processus parallèles impliquant une certaine inactivité (attente), ainsi que dans la synchronisation entre ces processus (messages ou événements). Autant de choses du monde réel fonctionne.
Fr13d

Il est intéressant de savoir que les sockets ont été conçus à l'origine comme une forme d'IPC sur une seule machine, avant la mise en réseau.

5

Les systèmes embarqués sont presque toujours intrinsèquement pilotés par les événements, même s'ils ne sont pas programmés explicitement comme tels.

Ces événements proviennent d'éléments tels que des interruptions matérielles, des appuis sur des boutons, des lectures périodiques analogiques / numériques, des expirations de minuterie, etc.

Les systèmes embarqués à faible puissance sont encore plus susceptibles d'être pilotés par les événements; ils passent la majeure partie de leur temps à dormir (le processeur en mode de veille), dans l’attente d’un événement (ce "quelque chose" est un événement).

La plate-forme QP (Quantum Platform) est l’un des frameworks les plus répandus et les plus populaires pour les systèmes embarqués pilotés par les événements. comme le programme n'est pas "séquentiel" au sens classique, il s'agit plutôt d'un ensemble de "rappels" qui sont appelés en fonction de l'état du système et de l'événement en cours.


3

Messages d'événement Gregor Hohpe.

Architectures pilotées par les événements Gregor Hohpe.

Architecture SEDA , Gallois, Culler, Brasseur.

comment gérez-vous dans la programmation backend normale quand quelque chose se passe faire cette autre chose?

La machine à états finis est une approche commune

Given(State.A)
When(Event.B)
Then(State.C)
    .and(Consequences.D)

2
1, ce n'est pas vraiment une réponse cohérente, et 2, FSM ne sont pas de bons exemples d'utilisation d'événements.
Whatsisname

1
FSM. Je suis sûr que la religion pastafarienne observe un certain nombre d'événements ;-)
13

0

Dans les systèmes embarqués, les événements se produisent pendant les interruptions. Il existe de nombreuses sources d'interruptions, des minuteries aux E / S.

En outre, le RTOS peut aussi avoir des événements. Un exemple est en attente d'un message d'une autre tâche.


0

Pour un système non intégré, mais quelque chose que je faisais en C # était un système SCADA. De nombreux événements liés à ce qui se passait dans l'entrepôt lorsque la charge était déchargée faisaient partie de l'événement généré par le système et que l'autre partie écrivait un nouvel état dans la base de données. Nous avions bien sûr un client graphique, mais c'était juste pour montrer l'état de la base de données qui reflétait l'état de l'entrepôt. C'était donc un logiciel serveur basé sur les événements et les threads. Assez difficile à développer.

https://en.wikipedia.org/wiki/SCADA

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.