Changelog
Ce qui est nouveau.
Chaque amélioration apportée à la plateforme, à mesure qu'elle est livrée.
· KBService
Verrouillez les balayages partagés, et lancez deux gousses
Chaque balayage programmé ici, dont l'effet est partagé, prend maintenant un bail distribué nommé par l'intermédiaire SingletonTaskRunner avant qu'il ne fasse quoi que ce soit, donc il court une fois sur la flotte au lieu d'une fois par jour. pod. C'était la seule chose qui gardait ce service dans une réplique - il n'y a pas de ShedLock n'importe où sur cette plate-forme, donc le nombre de réplique était ce qui rendait les balayages corrects. «Les transactions et les amis restent sur la méthode EXTÉRIEUR lorsqu'elle est présente: le printemps les applique avec un la méthode interne est atteinte par un: référence, qui ne passe jamais par une méthode. Les déplacer vers l'intérieur laisserait le balayage silencieusement non transactionnel. répliques de 1 à 2, avec un PodDisruptionBudget dans KlusterServices afin qu'un drain de nœuds attende.
· ESigService
Verrouillez les balayages partagés, et lancez deux gousses
Chaque balayage programmé ici, dont l'effet est partagé, prend maintenant un bail distribué nommé par l'intermédiaire SingletonTaskRunner avant qu'il ne fasse quoi que ce soit, donc il court une fois sur la flotte au lieu d'une fois par jour. pod. C'était la seule chose qui gardait ce service dans une réplique - il n'y a pas de ShedLock n'importe où sur cette plate-forme, donc le nombre de réplique était ce qui rendait les balayages corrects. «Les transactions et les amis restent sur la méthode EXTÉRIEUR lorsqu'elle est présente: le printemps les applique avec un la méthode interne est atteinte par un: référence, qui ne passe jamais par une méthode. Les déplacer vers l'intérieur laisserait le balayage silencieusement non transactionnel. répliques de 1 à 2, avec un PodDisruptionBudget dans KlusterServices afin qu'un drain de nœuds attende.
· AIService
Verrouillez les balayages partagés, et lancez deux gousses
Chaque balayage programmé ici, dont l'effet est partagé, prend maintenant un bail distribué nommé par l'intermédiaire SingletonTaskRunner avant qu'il ne fasse quoi que ce soit, donc il court une fois sur la flotte au lieu d'une fois par jour. pod. C'était la seule chose qui gardait ce service dans une réplique - il n'y a pas de ShedLock n'importe où sur cette plate-forme, donc le nombre de réplique était ce qui rendait les balayages corrects. «Les transactions et les amis restent sur la méthode EXTÉRIEUR lorsqu'elle est présente: le printemps les applique avec un la méthode interne est atteinte par un: référence, qui ne passe jamais par une méthode. Les déplacer vers l'intérieur laisserait le balayage silencieusement non transactionnel. répliques de 1 à 2, avec un PodDisruptionBudget dans KlusterServices afin qu'un drain de nœuds attende.
· kamo-internal
des sessions de codeur à côté des coquilles de courant, et une barre de défilement qui atteint les deux extrémités
Les terminaux sont maintenant à deux vues d'une machine Les sous-tabs plutôt que deux onglets de haut niveau, parce qu'ils ne sont pas deux destinations: a terminal est un shell qui peut exécuter une session, une session est une conversation qui peut avoir une coquille. L'interrupteur est une commande segmentée, pas une deuxième MUI Tabs Bande de deux barres de languette empilées comme chrome, un rail segmenté se lit comme "l'un des Ces deux", qui est ce qu'elle est. Chaque moitié porte sa propre création, donc un seul - dans l'en-tête du navigateur (qui ne pourrait jamais signifier que l'un d'entre eux) est maintenant montré uniquement pendant l'effondrement, où aucune ligne ne correspond. TerminalsWorkbench est partagé par le Centre d'interaction et le Centre d'interaction le navigateur, exactement comme TerminalsPane l'était déjà, donc les deux ne peuvent pas dériver. C'est prend la liste des terminaux comme un accessoire plutôt que de remettre l'interrogation - les deux surfaces le tenez déjà. Deux verbes, et lequel apparaît est l'état Une session déjà en cours dans un terminal dit «Ouvrir» et soulève cette fenêtre. Un qui n'est pas dit «Resumez» et ouvre un terminal qui le repout. Jamais les deux, et jamais une querelle handicapée. Reprise d'une session déjà joint une conversation deux têtes: les deux ICI écrivent à la même la transcription et la seconde s'ouvre en rejouant ce que la première est au milieu. La règle est une fonction, 'terminalForSession', donc rien ne peut y répondre deux fois et différemment. la machine laisse un reçu le moment où elle en prépare un - et dit plutôt plutôt qu'offrir de reprendre quelque chose qui n'a pas encore été écrit. Les sessions sont regroupées par jour. Quatre cent d'entre eux dans une colonne plane est un mur; les mêmes quatre cents sous Aujourd'hui / Hier / Au début de cette semaine / Avant cela est une liste que vous pouvez trouver hier après-midi. La liste tient compte de l'environnement. règles: la même géométrie de ligne et le rail 3px que la liste des terminaux, et la même division typographique - ce qu'une personne ou le modèle écrivait est placé dans celui de l'interface sans ce que la machine rapporte dans le mono de l'émulateur. Rien ici ne peut demander un mode d'autorisation. Chaque session commence par les autorisations contournées et qui sont décidées sur le dev machine; les noms de demande quelle séance et rien d'autre. Une broche de test que le client ne peut pas croître paramètre. La barre de défilement du terminal est propre xterm tire la barre grise du navigateur sur sa fenêtre, qui ne peut offrir que "un peu vers le haut" et "un peu bas". Dans un terminal, les deux extrémités ne sont pas deux autres positions. Ils sont les deux endroits que vous voulez vraiment, le début de ce que vous avez couru et le prompte - donc chacun obtient un bouton: saut à démarrer au-dessus de la flèche vers le haut, saut à bout sous la flèche vers le bas, avec une répétition enfoncée sur les flèches, clic-to-page sur la piste et un pouce glissant. La propre barre de xterm est cachée, pas Relié; la fenêtre de visualisation défile toujours, de sorte que la roue, le pavé tactile et le toucher sont inchangés. Le bouton à bout s'allume lorsque la sortie est arrivée sous le pli. Un terminal qui a cessé de suivre ressemble exactement à celui qui a fini, et c'est la seule chose que la barre sait que le lecteur ne peut pas voir. Vérification La porte pleine: 14 gardes de source et 5322 essais, plus tsc. La nouvelle interface utilisateur était également rendu dans un navigateur à partir d'un harnais local et lu plutôt que supposé - qui a capturé une puce de verbe transparent montrant le titre tronqué à travers le mot "Reprendre", et un état vide qui a cligné sur une machine avec quatre cents les sessions parce que le chargement est toujours faux sur le rendu avant l'effet. Les violations de l'AA WCAG AA sont nulles dans les nouveaux éléments. Le l'examen de travail porte son propre MotionConfig: le Centre d'Interaction enveloppe son panneau dans l'un, le navigateur ne le fait pas, et le mouvement de cadre à l'extérieur d'un anime droit Par le biais de la promotion de la baisse des préférences sans mot. Les clés du dictionnaire ont d'abord atterri, comme l'a demandé l'IC.
· SecurityService
Énumérer les sessions du codeur d'un membre et en ouvrir une dans un terminal
Deux critères d'évaluation à côté des terminaux, et ils suivent la même règle que ceux-ci : le compte Linux est résolu à partir de la SESSION DE L'APPUI et aucun nom de compte est jamais tirée de la demande. Un membre ne peut donc que voir ou rouvrir son les propres sessions - il n'y a pas d'id qu'ils pourraient fournir qui atteindraient quelqu'un sinon, parce que le compte ne fait pas partie de ce qu'ils fournissent. Une machine de développement inaccessible revient 200 avec «inaccessibilité»: true et un vide liste, comme le fait la liste des terminaux: "la machine est en panne" est quelque chose de l'onglet peut-on dire, où une erreur lui laisse tomber en mesure de ne rien dire. une nouvelle session ou une nouvelle session existante. Rien ne tourne lorsque le POST revient. La machine écrit la session et remet un récépissé; la fenêtre du terminal que la console ouvre ensuite présente son ticket ordinaire, et le récépissé est ce qui transforme ce terminal en cette session le même transfert d'utilisations de Send-A-A, par l'intermédiaire du même TerminalDispatchRegistry. L'identifiant de la fenêtre est nommé ICI parce que les deux moitiés en ont besoin: la console pour ouvrir le fenêtre, le registre pour mettre la clé du reçu, et tmux pour survivre à la reconnecte existe pour permettre. Ce point d'extrémité ne peut pas exprimer une commande, un modèle, un effort ou un mode d'autorisation. Chacun de ces est la machine à décider. Ce qui croise le fil, c'est lequel session, et rien d'autre - donc "bypassPermissions", que chacun d'entre eux les sessions s'exécutent avec, n'est pas un paramètre ici et ne peut pas en devenir un. TerminalSummary croupne de la coquille: la séance en cours d'exécution, lire l'option utilisateur tmux que l'agent définit. C'est ce qui laisse la console dire "déjà ouvert" au lieu de reprendre une conversation qui est vivant dans une autre Il n'y a nulle part d'autre que cela pourrait venir. L'ouverture de l'un est vérifiée exactement comme l'ouverture d'un obus est le même type d'événement, identique ÉHAUT sévérité - parce qu'il en est un. Vérifié avec le test de mvn; Java CI n'exécute aucun, donc un repo rouge serait toujours en train de se déployer.
· KlusterServices
Mesurer si un déploiement coûte effectivement une demande à toute personne
Chaque solution dans ce programme est une revendication sur ce qui se passe au cours d'un déploiement. Jusqu'à présent, ces réclamations n'ont pas fait l'objet d'essais: MediaService a été livré avec une stratégie Recréer dans une réplique toute sa vie, donc chaque déploiement a supprimé la seule boîte de serveur de discussion et de pièces jointes et a commencé le remplacement par la suite - un trou de 6 à 65 secondes, plusieurs fois par jour - et rien ne l'a mesuré. La première personne savait qu'un membre signalait un document défaillant, et même cela se lisait comme une caractéristique floconneuse plutôt que comme bavardage en bas à un horaire. Un exportateur de boîtes noires charge maintenant les huit hôtes publics toutes les 10 secondes. Dix, pas la valeur par défaut des années 30: la défaillance que cela existe à attraper est courte par conception, et à 30s un graphe propre ne signifierait que le Un trou est tombé entre deux éraflures. Deux alertes, et la seconde est la plus utile: PublicHostDown un hôte n'a pas répondu depuis une minute. Une panne, un déploiement ou non. PublicHostFlapping en dessous de 100 % de succès sur dix minutes. C'est celui qui capte un déploiement larguer une poignée de demandes - il récupère bien avant qu'un 1m "pour" s'embête, C'est précisément pourquoi cet échec est signalé comme "il m'a pratiquement enregistré et jamais comme un incident. Plus une alerte de certificat (le échec auto-signé à froid-Traefik n'avait pas de détecteur du tout), un coincé Alerte de déploiement, et une pour un déploiement assis sous le nombre de répliques souhaités - parce que Répliques: 2 aide seulement alors que la deuxième gousse est en fait en place, et qui n'est pas en bonne santé. La vérification TLS est délibérément activée: un certificat que cette plate-forme sert à tort doit échouer sonde, car c'est exactement ce qu'un Traefik froid faisait à chaque g/ou à la fois. la surveillance/n'est pas un objectif d'application de l'IC par convention de longue date ici, de sorte que les deux fichiers portent leur Existet sa propre ligne d'application.
· KlusterServices
sessions de codeur sur la machine dev, listée et réceptable
est ici, parce que la machine est la seule chose qui en sait. :: L'index de la session à la maison, exactement comme leurs terminaux sont tout ce qui est en train de faire. Pas de tableau, pour le la même raison: le disque sait déjà, c'est de quoi le CLI lui-même reprend, et Memoized on (mtime, taille), et il doit être - la machine qui a été construite contre tient 444 sessions et 1,1 Go de transcription, dont 205 Mo. Uniquement le premier et 128 ko dernier de chaque fichier sont lus: le répertoire de travail, la branche et le l'ouverture est indiquée dans les premiers enregistrements, le titre généré et le résumé sont les suivants: en annexe à la session, et le milieu est l'appel d'outils. Mesurée contre le vrai magasin: 2,8 s froid, 17 ms chaud. Deux choses qu'une transcription ne peut pas dire Une transcription n'indique pas que la console l'a commencé, donc une session a commencé sans que la ligne qu'un membre qui vient de créer soit absente de la liste, ils sont En regardant, qui se lit comme le bouton n'ayant rien fait. Et une transcription n'enregistre pas où elle est chassée, donc une coquille qui est en train d'exécuter un porte maintenant l'id de session en tant qu'option utilisateur tmux (kamo-coder), à côté du titre qui y vit déjà. C'est l'ensemble de la règle duplicata: la reprise d'une session qui est déjà attachée donne une conversation à deux têtes. avec les deux CLI en écrivant sur une transcription et la seconde rejouant ce que la première est au milieu de. La liste croît donc d'un champ, donc les sessions de la liste demande maintenant sept - le titre reste LAST et la scission reste limitée, parce que le séparateur est imprimable et un organe peut le taper. L'appelant n'a toujours jamais fourni de commandement La ligne de commande est composée ici: le chemin de l'ICL résolu sous le compte la maison propre, la séance id atprimait ou trouvée sur ce disque, et --permission-mode byor Permissions-Permissions-, qui n'est pas un paramètre et ne peut pas être l'un. Les dossiers établis portent maintenant un «kind», et un qui est antérieur au champ est un Envoyer-to-AI, ce qui est le seul type qu'il y en avait. Le répertoire de travail est la seule chose qu'une demande peut influencer et est limité par le réalisme vers la maison du compte. Ce n'est pas une limite de privilège - le terminal fonctionne déjà comme ce compte - il conserve l'ensemble des annuaires a DEMANDE peut nommer plus petit que l'ensemble qu'une personne peut atteindre. Un enregistrement qui nomme un le compte n'est également remboursable que par le terminal de ce compte. 40 nouveaux tests, 199 dans la suite, tous passant. L'indice est vérifié par rapport à la magasin réel de 444 sessions plutôt que d'accessoires seuls. Les navires par install-agent.sh, pas par CI: pousser cela ne se déploie rien à la VM.
· KlusterServices
Budget de toutes les ponctionnements et échouer un déploiement qui régresse la sécurité de déploiement
PodDisruptionBudgets pour les 25 déploiements qui fonctionnent maintenant vraiment deux répliques. minDisponible: 1 laisse un drain expulser une dose et attendre son remplacement au lieu de prendre un noeud entier. à la fois. L'espace de noms kamo avait l'indice de zERO de ceux-ci tandis que les services de cluster, kamo-universe, le système longhorn et le kubevirt les avaient tous - l'espace de noms contenant la production était celui qui n'en avait pas. Seuls les déploiements en fait à deux répliques apparaissent. Un PDB sur un déploiement à une seule réplique est pire minDisponible: 1 contre les répliques: 1 permet zéro perturbation, de sorte qu'il ne protège pas la charge de travail, il bloque la maintenance des nœuds pour toujours. README.md dit ainsi, et nomme le délibéré des singletons qui ne doivent jamais être listés. scripts/audit-deploy-safety.sh échoue dans le déploiement si un déploiement en kamo a dérivé vers une forme qui laisse tomber les requêtes au cours d'un déploiement: pas de sonde de préparation, pas de pré-stop, pas de minReadySeconds, Recréer sans opt-out, ou deux répliques avec rien qui les répand entre les nœuds. Il vérifie le CLUSTER plutôt que les manifestes. Ces paramètres vivent dans 48 référentiels distincts avec 48 flux de travail; un garde-disque per-repo attraperait une régression plus tôt, mais il est de 48 copies à conserver en pas et en tout nouveau-requête qui n'adopte jamais, il est silencieusement exempté. Chacun de ces manifestes finit Ici. Le commerce est qu'il s'agit d'un avertisseur de fumée plutôt que d'une écluse - il rapporte après les faits, donc il imprime l'ensemble du tableau et nomme ce qui a dérivé plutôt que de simplement échouer. Les exemptions sont des annotations sur le déploiement lui-même, et une raison est obligatoire: une exemption Sans l'un d'eux est un échec. C'est ce que laisse la personne suivante dire un singleton délibéré (kamodaemon lie NATS durable exclusif) de quelque chose que personne n'a fait son arrondi.
· RAGService
Partager les consommateurs d'indexation et faire deux gousses
RAGService lie deux biens durables JetStream de sa propre valeur de référence - rag-not-consommateur et rag-kb-consommateur - et un consommateur de poussée durable sans groupe de livraison admet exactement UN abonné. Une deuxième position serait ont été refusés [SUB-90012, en laissant l'indexation épinglée à la nd, quelle que soit la pod liée en premier avec Rien ne prend le relais quand cette gousse est celle qui meurt. Les deux rejoignent maintenant un groupe de livraison, de sorte que NATS tend chaque événement à exactement une dose. C'est ce qui indexe besoin: une fois, pas une fois par dosette, et pas une fois par dosette qui a gagné une course. répliques de 1 à 2 Ce service ne fonctionne pas «Télébré» et ne lie aucune NATS exclusive durable, donc a La deuxième dose ne fait double emploi - c'est une demande d'apatride servant, et la seule chose à garder à Une réplique était que rien n'avait soulevé le nombre. Dans une réplique maxSurge cache l'exposition lors d'un déploiement propre et nulle part ailleurs: un OOM tuer, a Une sonde de vie défaillante ou un drain de noeud a entièrement pris la capacité pendant les 59-79 secondes a Le contexte de printemps prend pour démarrer. Un PodDisruptionBudget dans KlusterServices fait maintenant un drain wait.
· VectorService
Exécuter deux gousses
répliques de 1 à 2 Ce service ne fonctionne pas «Mesure programmée et ne lie aucune NATS exclusive durable, donc a La deuxième dose ne fait rien, c'est une demande d'apatride servant, et la seule chose à maintenir Une réplique était que rien n'avait soulevé le numéro. Dans une réplique maxSurge dissimule l'exposition pendant un déploiement propre et nulle part ailleurs: un OOM tuer, a Une sonde de vie en panne ou un drain de noeud a complètement pris la capacité pendant les 59-79 secondes a Le contexte de printemps prend pour démarrer. Un PodDisruptionBudget dans KlusterServices fait maintenant une attente de drain.
· ConversionService
Exécuter deux gousses
répliques de 1 à 2 Ce service ne fonctionne pas «Mesure programmée et ne lie aucune NATS exclusive durable, donc a La deuxième dose ne fait rien, c'est une demande d'apatride servant, et la seule chose à maintenir Une réplique était que rien n'avait soulevé le numéro. Dans une réplique maxSurge dissimule l'exposition pendant un déploiement propre et nulle part ailleurs: un OOM tuer, a Une sonde de vie en panne ou un drain de noeud a complètement pris la capacité pendant les 59-79 secondes a Le contexte de printemps prend pour démarrer. Un PodDisruptionBudget dans KlusterServices fait maintenant une attente de drain.
· APIService
Exécuter deux gousses
répliques de 1 à 2 Ce service ne fonctionne pas «Mesure programmée et ne lie aucune NATS exclusive durable, donc a La deuxième dose ne fait rien, c'est une demande d'apatride servant, et la seule chose à maintenir Une réplique était que rien n'avait soulevé le numéro. Dans une réplique maxSurge dissimule l'exposition pendant un déploiement propre et nulle part ailleurs: un OOM tuer, a Une sonde de vie en panne ou un drain de noeud a complètement pris la capacité pendant les 59-79 secondes a Le contexte de printemps prend pour démarrer. Un PodDisruptionBudget dans KlusterServices fait maintenant une attente de drain.
· kamo-internal
Répondre à une sonde de préparation et lancer deux gousses
Ce déploiement n'avait pas de sonde de préparation, donc une nacelle a compté comme prêt l'instant son conteneur processus entamé. Avec maxUnavailable 0 Kubernetes dit que "la nouvelle gousse est en service" et prend sa retraite l'ancienne - tandis que Next est toujours en train de initialiser et n'a pas lié son port. Demandes débarquées sur un port, rien n'écoutait, c'est d'où provenait les 502 en train de déployer. /api/santé ne répond que pour cette dosette et ne touche délibérément pas d'arrière-plan: une sonde de préparation décide si cette gousse quitte le Service, et le coupler à un backend transforme un blip dorsal en un Relancer le redémarrage de chaque gousse ici. Le drain et le délai de grâce des 660 étaient déjà là; la sonde manquante est ce qui les a arrêtés comptage. Kubernetes retirait la gousse de drainage avant que le remplacement puisse servir. répliques de 1 à 2. L'état côté serveur vit à Redis, pas dans la navure, et il n'y a pas de travail programmé à dupliquer, donc une seconde réplique ne change rien d'autre que la perte d'une nacelle cesse d'être une panne. Dans une réplique, une destruction d'OMO, une sonde de vie ratée ou un drain de nœud a pris le tout pour tant qu'il faut pour démarrer. topologieSpreadConstraints (ajoutés plus tôt, inertes jusqu'à présent) gardent les deux sur des nœuds différents où le cluster peut le gérer, et un PodDisruptionBudget dans KlusterServices fait attendre un drain.
· kamo-marketing
Égoutter sur SIGTERM et faire fonctionner deux gousses
Le suivant gère SIGTERM avec un processus nu.exit(143), de sorte que chaque déploiement a sectionné n'importe quelle nantie avait en vol - un message de formulaire, une action serveur, une charge utile RSC en continu, un téléchargement. Invisible lorsqu'a demande a duré des millisecondes; pas invisible sur un cluster qui se déploie sur chaque poussée. scripts/standalone-entry.cjs enveloppe le serveur autonome: sur SIGTERM, il cesse d'accepter, les chutes de ralenties garde-alives à la fois donc une nacelle avec rien en vol sort encore en environ une seconde, et laisse courir les demandes se terminent sous un plafond qui se trouve en dessous de l'extrémitéGracePeriodsSeconds. Porté à partir de kamo-internal, qui le dirige en production depuis des mois. L'enveloppe démarre serveur-nonce.js plutôt que server.js, via NEXT-SERVER-ENTRY et le CSP nonce Un serveur reste exactement là où il se trouvait dans la chaîne. répliques de 1 à 2 L'état du serveur vit à Redis, pas dans la nacelle, et il n'y a pas de travail programmé à dupliquer, donc une seconde réplique ne change rien sauf que la perte d'une nacelle cesse d'être une panne. Dans une réplique, une mort OOM, une sonde de vie ratée ou un drain de nœud a pris le tout pour tant qu'il faut pour démarrer. topologieSpreadConstraints (ajoutés plus tôt, inertes jusqu'à présent) gardent les deux sur des noeuds différents où le cluster peut le gérer, et un PodDisruptionBudget dans KlusterServices fait attendre le drain.
· kamo-capcha
Exécuter deux gousses
répliques 1 - 2 L'état du serveur vit dans Redis, pas dans la nacelle, et il n'y a pas de travail programmé pour dupliquer, donc une seconde réplique ne change rien sauf que la perte d'une nacelle cesse d'être une panne. Dans une réplique, une mort OOM, une sonde de vie ratée ou une fuite de nœuds a pris le tout pour tant qu'il faut pour démarrer. topologieSpreadConstraints (ajoutés plus tôt, inertes jusqu'à présent) gardent les deux sur des nœuds différents où le cluster peut le gérer, et un PodDisruptionBudget dans KlusterServices fait une attente de drain.
· kamo-register
Égoutter sur SIGTERM, répondre à une sonde de préparation et faire fonctionner deux gousses
Ensuite, SIGTERM avec un processus nu.exit(143), donc chaque déploiement a sectionné n'importe quelle nupe poêle avait en vol - un poste de formulaire, une action serveur, une charge utile RSC en continu, un téléchargement. Invisible lorsqu'un demande a duré des millisecondes; pas invisible sur un cluster qui se déploie sur chaque poussée. scripts/standalone-entry.cjs enveloppe le serveur autonome: sur SIGTERM il cesse d'accepter, les gouttes ne sont pas au repos keep-alives à la fois donc une gousse avec rien en vol sort encore en environ une seconde, et laisse courir demandes de fin de brevetFrémundes sur les deux cas dans le paragraphe. Porté de kino-interne, qui le gère en production depuis des mois. Ce déploiement n'avait pas de sonde de préparation, donc une gousse comptée comme prête à être prête à l'instant son conteneur processus entamé. Avec maxUnavailable 0 Kubernetes dit que "la nouvelle dosette sert" et prend sa retraite l'ancienne - tandis que Next est encore en train de initialiser et n'a pas lié son port. Demandes débarquées Sur un port, rien n'écoutait, c'est-à-dire de l'origine des 502 en déploiement intermittents. /api/satisfait répond uniquement à cette dosette et ne touche délibérément pas de backend: une sonde de préparation décide si cette gousse quitte le Service, et le câbler à un back-end déclenche un blip en un Relancer le redémarrage de chaque gousse ici. Le Dockerfile HEALTHCHECK a pointé du doigt/api/santé depuis son écriture; l'itinéraire n'a pas été tracé. existent, de sorte que ce contrôle échoue depuis longtemps qu'il y a été trouvé. répliques de 1 à 2. L'état du serveur vit dans Redis, pas dans la nacelle, et il n'y a pas de travail programmé à dupliquer, donc une seconde réplique ne change rien sauf que la perte d'une nacelle cesse d'être une panne. Dans une réplique, une mort OOM, une sonde de vie ratée ou un drain de nœud a pris tout le truc pour tant qu'il faut pour démarrer. topologieSpreadContraints (ajoutés plus tôt, inertes jusqu'à présent) gardent les deux sur des noeuds différents où le cluster peut le gérer, et un PodDisruptionBudget dans KlusterServices fait attendre un drain.
· kamo-login
Égoutter sur SIGTERM, répondre à une sonde de préparation et faire fonctionner deux gousses
Ensuite, SIGTERM avec un processus nu.exit(143), de sorte que chaque déploiement a sectionné n'importe quelle nacelle avait en vol - un poste de formulaire, une action serveur, une charge utile RSC en streaming, un téléchargement. Invisible lorsqu'il s'agit d'un demande a duré des millisecondes; pas invisible sur un cluster qui se déploie sur chaque poussée. scripts/standalone-entry.cjs enveloppe le serveur autonome: sur SIGTERM, il cesse d'accepter, les gouttes ne sont pas retournées keep-alives à la fois donc une gousse avec rien en vol sort encore dans environ une seconde, et laisse courir les demandes se terminent sous un plafond qui se trouve en dessous de la terminaisonGracePeriodSeconds. Porté de kmo-interne, qui le gère en production depuis des mois. Ce déploiement n'avait pas de sonde de préparation, donc une gousse comptée comme prête à être prête à l'instant son conteneur processus entamé. Avec maxUnavailable 0 Kubernetes dit que "la nouvelle dosette sert" et prend sa retraite l'ancienne - tandis que Next est encore en train de initialiser et n'a pas lié son port. Demandes débarquées Sur un port, rien n'écoutait, d'où provenait les 502 intermittents en déploiement. /api/sapi répond uniquement pour cette dosette et ne touche délibérément pas de backend: une sonde de préparation décide si cette nacelle quitte le Service, et le câbler à un backend transforme un blip dorsal en un Rehausser le redémarrage de chaque gousse ici. répliques de 1 à 2. L'état du serveur vit dans Redis, pas dans la gousse, et il n'y a pas de travail programmé à dupliquer, donc une seconde réplique ne change rien, sauf que la perte d'une nacelle cesse d'être une panne. Dans une réplique, une mort OOM, une sonde de vie en panne ou une fuite de nœuds a pris tout pour tant qu'il faut pour démarrer. topologieSpreadConstraints (ajoutés plus tôt, inertes jusqu'à présent) gardent les deux sur des noeuds différents où le cluster peut le gérer, et un PodDisruptionBudget dans KlusterServices fait attendre un drain.
· kamo-nowww
Égoutter sur SIGTERM et répondre à une sonde de préparation
Ensuite, SIGTERM with a nue process.exit(143), de sorte que chaque déploiement a sectionné n'importe quelle nacelle avait en vol - un poste de formulaire, une action serveur, une charge utile RSC en continu, un téléchargement. Invisible lorsqu'il s'agit d'un la demande a duré des millisecondes; pas invisible sur un cluster qui se déploie sur chaque poussée. scripts/standalone-entry.cjs enveloppe le serveur autonome: sur SIGTERM il cesse d'accepter, les gouttes ne sont pas ralenties keep-alives à la fois donc une gousse avec rien dans le vol sort encore en environ une seconde, et laisse courir demandes de finition sous un plafond situé en dessous de terminationGracePeriodsSeconds. Porté de kmo-interne, qui le dirige en production depuis des mois. Ce déploiement n'avait pas de sonde de préparation, donc une gousse comptée comme prête à être prête dès lors son conteneur. processus entamé. Avec maxUnavailable 0 Kubernetes dit que "la nouvelle gousse est en service" et prend sa retraite l'ancien - tandis que Next est encore en train de initialiser et n'a pas lié son port. Demandes débarquées sur un port, rien n'écoutait, c'est-à-dire d'où venaient les 502 intermittents en déploiement. /api/sapi ne répond que pour cette navette et ne touche délibérément pas de backend: une sonde de préparation décide si cette gousse quitte le Service, et le câbler à un back-end tourne un blip de backend en un Relancer le redémarrage de chaque gousse ici. Déjà en deux répliques; c'est ce qui fait que la seconde couvre effectivement la première lors d'un Déroulement plutôt que d'être remplacés aveugles.
· kamo-shared-library
Une serrure distribuée, donc un balayage programmé peut survivre à une deuxième réplique
Il n'y a pas de ShedLock nulle part sur cette plate-forme et il n'y en a jamais eu. Tous les 97 «Scheduled» Les balayages sur 18 services ne sont corrects que parce que chaque service fonctionne exactement une dose. Échelle de l'un quelconque des eux et le balayage passe deux fois par une tique - deux rappels de réunion dans la boîte de réception d'un membre, deux chats-email avis, deux laissez-passer sur une période de facturation. Ces déploiements à réplique unique n'étaient pas simplement non-échelle; le nombre de répliques était en train de porter la charge, et le code le dit à trois endroits déjà. - location, corps) gère un corps sur exactement une nacelle. UNE APPEL D'EXPLICIT, PAS UNE ANNOTATION. SingletonTask à côté de la machine est la conception évidente et elle est un piège ici: il serait appliqué par un mandataire de l'AOP, et un mandataire est entièrement contourné lorsqu'une méthode est atteint de l'intérieur du même haricot - le problème d'auto-invocation du printemps, cette base de code a été pris par cinq fois séparément. Un balayage qui a silencieusement perdu sa serrure et a couru sur chaque pod est que le même échec, et rien ne le révélerait jusqu'à ce qu'un client comptabilise ses e-mails. Prendre la serrure par l'appel ne peut pas être contourné par la façon dont la méthode a été atteinte, et il greps. REDIS, PAS LA BASE DE DONNÉE. Une table de verrouillage a besoin de DDL, et DDL sur ce cluster fait toutes les réponses de service 500 «disparting de version deschema» pour plus de 15 minutes pendant que les connexions Hikari vieillissent. Paiement d'un Une panne à l'échelle de la plate-forme pour installer la machine qui empêche les pannes à l'échelle de la plate-forme est un mauvais commerce lorsque Redis est déjà déployé. FAILES FERMÉS. Si Redis n'est pas joignable, la tâche est sautée, ne pas exécuter: pour le travail qui envoie des e-mails ou bougent l'argent, courir deux fois est pire que de ne pas courir, et la prochaine recherche de coches. La libération est un comparer et supprimer l'écriture de sorte qu'un corps qui surpasse son bail ne peut pas supprimer une serrure une autre gousse a depuis qu'il a été pris, et le dépassement est enregistré à l'ERROR parce que rien d'autre ne le révélerait. Là où un service n'a pas Redis le retour passe toujours à l'intégrité - exactement ce que le code fait aujourd'hui, L'adoption de ce point ne change jamais de comportement en soi - et avertit au démarrage. Le garde manifeste en IC refuse les répliques de plus de 1 pour un service dans cet État. 7 essais; suite complète 2710 vert.
· kamo-register
Peinture de chaque logo sur le site d'inscription dans la couleur superposition de l'orge
L'organisation choisit "Register le logo du site Overlay" en kémo-interne à côté de la page d'accueil et superpositions d'écran de chargement. Un cadre pour l'ensemble du site: chaque étape du flux d'enregistrement, l'organisation et les écrans d'équipe, l'écran de finition et l'écran d'inscription fermé. Donc ThemeLogo ne prend pas d'accessoire pour lui et lit la couleur elle-même, la façon dont il Identifiant déjà l'identité du logo de la société-vs-software - config.json est la seule source d'images d'org de ce site, et un accessoire serait un de plus Il faut se rappeler chaque site d'appel. La couleur arrive déjà résolue: le kamo-internal stocke un TOKEN donc un org qui rebrands garde une superposition correspondante, et le service de sécurité résout contre la palette de cette org quand elle écrit config.json. Rien ici a besoin du vocabulaire de treize jetons. Une valeur CSS ne peut pas être supprimée plutôt que de passer - un fond invalide peint le masqué Boîte transparente, qui se lit comme un logo qui a disparu. Un masque, pas un filtre: un filtre ne peut que pousser les couleurs existantes d'un logo autour et ne peut pas atteindre une cible arbitraire. Le 'img' reste monté et simplement invisible afin qu'il continue à tenir sa case exacte pour que le masque rempli, laissant la disposition de chaque appelant inchangée. Sa propre colonne et sa propre clé config.json, distincte de la connexion site: les deux sont marqués indépendamment, et un org qui marque les marques blanches l'un n'a pas besoin d'être blanc sous le même étiquetage.
· kamo-login
Peinture de chaque logo sur le site d'inscription de la couleur superposition de l'org
L'organisation choisit "Login Site Logo Overlay" en kémo-interne à côté de la maison p. et superpositions d'écran de chargement. Un cadre pour l'ensemble du site: le formulaire de connexion, le sélecteur d'espace de travail, la récupération et la réinitialisation du mot de passe, et L'écran de signature est le même logo sur le même fond, et personne ne veut pour fixer la teinte cinq fois. Donc ThemeLogo ne prend pas d'accessoire pour lui et lit la couleur elle-même, la façon dont elle Identifie déjà l'identité du logo de l'entreprise-vs-software - config.json est la seule source d'images d'orgue de ce site, et un accessoire serait un autre toute chose dont tout site d'appel doit se souvenir. La couleur arrive déjà résolue: le kamo-interne stocke un TOKEN donc un ug qui rebrandissent garde une superposition correspondante, et le service de sécurité résout contre la palette de cette org quand elle écrit config.json. Rien ici a besoin du vocabulaire de treize jetons. Une valeur CSS ne peut pas être supprimée plutôt que de passer - un fond invalide peint le masque Boîte transparente, qui se lit comme un logo qui a disparu. Un masque, pas un filtre: un filtre ne peut que pousser les couleurs existantes d'un logo autour et ne peuvent pas atteindre un objectif arbitraire. Le 'img' reste monté et simplement invisible pour qu'il soit toujours allumé sur Los Angeles (la seule source de naturalSize) et onError (qui assure la sortie complète du logo, l'extension pleine de coups de côté), et donc il tient toujours sa case exacte pour que le masque puisse le remplir. La disposition de chaque appelant est inchangé. La petite marque d'animation dans la pilule "Powered by KamoCRM" est la sienne. logo aussi, il suit donc le réglage - il rend juste à travers la prochaine/image pour la charge avide de cette pilule, donc elle porte le masque lui-même plutôt que Devenir un logo thématique. D'autre part, il aurait été le seul logo sur le le réglage manqué.
· kamo-internal
Choisir un logo superposition pour les sites d'inscription et d'inscription
Un quatrième et cinquième emplacement à côté de la page d'accueil, un écran de chargement et KamoMeets superposés, partageant leur vocabulaire de treize jetons et leur vie des voiles. Les deux sont toujours offerts, contrairement au KamoMeets un: chaque org a une connexion et un site d'inscription quelle que soit l'application qu'il exécute, et un org sans domaine de son s'apparier leur parvient toujours sur login./register.kamocrm.com peint dans son propre image. Ils sont aussi les deux seules superpositions ici qui n'appliquent pas le moment où ils Sauvegarder. kmo-login et kamo-register n'ont pas d'OrgContext à lire, donc le service de sécurité résout le jeton et embrasse la couleur dans le thème config.json ces sites fetchol; le changement de terrain lors de la remise en état des réécritures ce fichier, qui sauvegarde déjà le même déclenche. Cinq déroulations presque identiques auraient été cinq endroits pour dériver, donc le Le bloc de l'éditeur est maintenant un renderOverlaySelect() les surfaces partagent - un sixième surface est un appel plutôt qu'une autre vingt lignes. Les lignes en lecture seule Déjà partagé les leurs. Les deux champs circulent Organisation. de JSON comme leurs frères et sœurs, avec un test aller-retour: le mapperage s'exécute deux fois sur le chemin du navigateur, et a champ qu'il ne peut pas lire à partir de sa propre sortie est un réglage qui silencieusement revient sur sa charge suivante.
· MediaService
Faire en sorte que MediaService corrige plus d'une dosette et en exécuter deux
MediaService n'a jamais exécuté qu'une seule réplique, donc un déploiement de celui-ci était une panne totale de chat et Un OOM était le même. Il ne peut pas en exécuter deux, pour des raisons qui figuraient dans le code: 1. THE STOMP BROKER IS IN-HEAP. enableSimpleBroker signifie convertPartingSend n'atteint que les WebSockets connectés à la nacelle faisant l'appel. Treize contrôleurs relais ont déjà géré correctement cela. en s'abonnant à NATS avec un répartiteur clair (pas de groupe de file d'attente, de sorte que chaque gousse reçoit chaque et republiant localement. Treize autres sites d'appel n'ont pas été les suivants: indicateurs de dactylographie, présence, badges non lus, subventions de réponse, offre WebRTC/réponse/ICE, notifications de cachet entrants et chacun aurait livré à environ la moitié de son public. StompFanout généralise le modèle que ces relais utilisent déjà: publier l'adresse suivante: un sujet de base NATS, chaque gâche le transmet à son propre courtier. Core NATS, pas JetStream, parce qu'il s'agit d'événements en direct sans valeur rejouée et aucun flux couvrant le sujet. Parce que la NATS de base livre également à l'éditeur, send() n'écrit PAS aussi localement - que serait prêt à être livrés deux fois ici. Avec NATS en bas, il retombe à un envoyé local, qui est ce que la plate-forme l'a fait auparavant. 2. Le consommateur de la PER-CONVERSATION était un concurrent EXCLUSIF. ChatSessionAbondienManager nommé JetStream durable après la session de discussion GUID, et un consommateur de poussée durable en admet exactement un abonné. La contrainte de la deuxième nacelle a été refusée [SUB-90012 et de tous les membres dont la douille a atterri Il n'y a rien reçu - pas de messages, pas de reçus de lecture, pas d'événements ajoutés aux membres, pas d'erreur. Maintenant un consommateur éphémère: pas de nom pour entrer en collision, un par dosette, récolté par le serveur. Le réessai qui supprime un nouveau nom durable en cas de collision. Il a fonctionné, et il a divulgué une consommateur permanent côté serveur par collision que rien n'a jamais supprimé. 3. CUES PLUS D'UNE DURABLES FIXES, nécessitant un traitement opposé en fonction du travail. La conversion et les relais VOIP STOMP sont passés par JetStream plutôt qu'un répartiteur de base, de sorte qu'ils avaient les mêmes un bug d'exclusivité - maintenant éphémère, puisque chaque gousse doit recevoir. Le notifiant de chat-email, social le consommateur entrant et le consommateur de commercialisation doivent fonctionner exactement EN COURS, de sorte qu'ils gardent leur durable et rejoindre un groupe de livraison, ce qui signifie également qu'un survivant reprend l'œuvre lorsqu'une gousse meurt. Des sessions collantes sur l'itinéraire du média sont nécessaires, et non facultatives: ces clients STOMP utilisent SockJS, dont la rupture xhr-streaming/xhr-polling est de plusieurs requêtes HTTP pour une connexion contre la session stipule que vit dans la mémoire d'une gousse. La rouche ronde le casse. Voir ingressroute.yaml. répliques de 1 à 2. 367 tests passent.
· SecurityService
Cuire l'inscription et inscrire le logo superposé dans config.json
kmo-login et kamo-register run sur leurs propres hôtes sans OrgContext, donc ce fichier est la seule voie que leur marque prend - le même KamoMeet déjà utilisés. Le jeton est résolu contre la palette de l'organisation ICI et le l'hexe fini est écrit, ce qui maintient le vocabulaire de treize voix à deux autres bases de code qui auraient chacune besoin de sa propre copie. Le cuisson d'une couleur résolue n'est pas l'erreur que le jeton stocké évite: le fichier est régénéré sur chaque image de marque, les changements de couleur inclus, donc la valeur ne peut pas aller périmé. Absent signifie pas de overlay, donc un org qui n'a choisi aucun gain de clé et ses logos ne sont pas modifiés, ce qui est chaque org jusqu'à ce que l'on soit choisi. Les essais couvrent les trois surfaces qui restent à l'écart: ils partagent un constructeur, et une orgueil superposant son site d'inscription ne doit pas être peint son logo KamoMeet en tant qu'effet indésirable.
· kamo-shared-library
Une superposition de logo pour les sites d'inscription et d'inscription
Deux autres colonnes dans le vocabulaire home-logo-overlay déjà établies: un jeton, pas un hexagone, donc un orgon qui rebrands garde une superposition correspondant à son de nouvelles couleurs. Les deux annulables sans remblai - nul n'est rien, ce qui est ce que Chaque org ressemble à aujourd'hui. Des colonnes séparées plutôt qu'un cadre partagé, pour la même raison La page d'accueil et l'écran de chargement ont leur propre: les deux sites sont marqués indépendamment, et une orge qui marque les marques blanches, il n'est pas nécessaire qu'il soit en marque blanche l'autre. patch Organization est un ALLOW-LIST, donc les noms vont là aussi. Une colonne ce service désérialise heureusement mais cette méthode n'est pas nom accepté avec un 200 et silencieusement jamais stocké - pas d'erreur, pas de ligne logarithmique, et le seul symptôme est un réglage qui revient sur sa prochaine charge.
· kamo-login
Répondre au lien dans une lettre de changement d'adresse
/verify-email-change dépense le jeton dans une lettre de changement d'adresse et dit Ce qui s'est passé. Il vit ici plutôt que dans l'espace de travail parce que la lettre va dans une boîte aux lettres PERSONNEL - généralement lue sur un téléphone qui n'a jamais été connecté l'espace de travail, et souvent non connecté à quoi que ce soit. hôte qui se décide toujours pour une organisation et n'a jamais besoin d'une session, donc il est le seul endroit où le lien est certain de travailler pour la personne qui en a le plus besoin. Rien sur la page ne demande quoi que ce soit. Il arrive, dépense le jeton, et - un formulaire ici serait un formulaire que le lecteur ne peut pas remplir à partir du une boîte aux lettres qu'ils ont ouverte. Les dépenses sont protégées contre le développement de React double-invoke, parce que le jeton est à usage unique et qu'un deuxième appel le dépenserait et signalons ensuite le succès car "ce lien n'est plus valable". Le relais à côté de /api/recover et façonné de la même manière: SecurityService est ClusterIP uniquement, donc il passe au-dessus du cluster DNS, ce qui fait de Host le nom du service et met le nom d'hôte du navigateur dans X-Forwarded-Host - le seul en-tête de la backend le lit à partir de.
· kamo-internal
Changez votre propre adresse et un onglet de plate-forme pour chaque compte
Deux surfaces, jointes par une distinction, la plate-forme n'a jamais expliqué à n'importe qui: un compte utilisateur est la PERSONNE, et un membre est un membre d'une organisation relation avec cette personne. Mon profil gagne une carte d'adresse e-mail personnelle, dans la salle d'accès à côté du mot de passe parce que c'est ce qu'il est - l'un des trois identifiants de signature accepte, et l'adresse à laquelle un mot de passe est envoyé par la poste. Le déposer en contact les détails seraient de déposer une clé sous la papeterie. Il s'engage lui-même plutôt que en passant par le bar de sauvegarde de la pièce: un changement est une demande, une lettre et un confirmation, et un bouton Save qui a écrit un identifiant de connexion sans preuve la boîte aux lettres existerait l'ensemble du problème dans un seul contrôle. Le compte appartient à l'organisation nommée par Security-provider-id, et seul que l'on peut le changer. La carte est donc visible partout et éditable en une place - le cacher dans les autres laisserait un membre à la recherche d'un décor qui semble avoir été supprimé. Là où il ne peut pas être édité, il dit qui il est est, et offre les deux chemins de retour: passer du menu du haut côté gauche sans partir l'application, et la signature directement à l'adresse d'inscription de cette organisation (ou, lorsqu'il n'en a pas encore, au nom de celui-ci). Les deux viennent de OrgEntryDomainResolver, donc l'hôte n'est jamais un hôte qui ne parvient pas à résoudre. Un expliquant s'assoit sous la carte sur TOUTE organisation, pas seulement à l'intérieur du le refus. "Compte d'utilisateur" contre "compte d'organe" est une distinction de personne d'extérieur la plate-forme a une raison quelconque de savoir, et elle devient porteuse à l'état exactement moment quelqu'un se voit refuser quelque chose - qui est le pire moment possible pour se rencontrer une idée pour la première fois. /account gagne un quatrième onglet, Utilisateurs, fermé sur la nouvelle plateforme MANAGE-USERS C'est vrai. La droite porte déjà "l'organisation actuelle doit être la plate-forme La plate-formeRightsResolver ne rend rien au tout session à l'intérieur d'un locataire - de sorte que l'onglet ne vérifie pas l'organisation séparément; une deuxième autorité ne pouvait jamais être en désaccord avec le serveur. Recherche et la radiosage sont aussi celles du serveur: le filtre de la grille recherche les lignes qu'il se produit de maintenir, qui, sur un tableau à l'échelle de la plate-forme, signifie la communication "pas de résultats" pour un compte qui existe. Le tiroir derrière une ligne est bande par conséquence plutôt que par sujet. Identité éditant un projet et sauvegarde une fois; l'état du compte est commis par commutateur et rapports combien de séances se sont déroulées avec elle; la reprise est mise à part et confirmée. Dieu les comptes et l'utilisateur du système rendent en lecture seule, parce que le serveur les refuse et composer une édition qui n'allait jamais à la terre est pire que d'être dit d'abord. Corrige également la bannière du fournisseur de sécurité qui a toujours été sur cette page. Il a établi son lien à partir de l'identifiant membre de l'organisation. nom d'hôte qui n'est pas l'hôte de l'espace de travail, à un membre id qui n'existe pas Là. Il pointe maintenant sur l'écran de connexion que le serveur résout.
· kamo-shared-library
Ajouter un groupe de file d'attente, donc le travail est partagé plutôt que codé à une seule dose
Compagnon de souscriptionEphemeral. Deux emplois différents, deux consommateurs différents: abonyEphemeral chaque pod doit voir tous les messages (tout se terminant par une diffusion STOMP) subscribeQueue le travail doit se faire exactement ONCE (envoi d'un e-mail, appel d'un fournisseur) Ce n'est pas non plus ce qu'un simple durable fait à plus d'une réplique. En l'absence de groupe de livraison, une poussée durable Le consommateur admet un abonné unique, de sorte que la deuxième gousse est refusée [SUB-90012 et l'œuvre est cloué à n'importe quelle position liée en premier - sans rien prendre le dessus si c'est la gousse qui meurt. L'ajout d'un groupe de livraison transforme la même durabilité en une file d'attente que les gousses partagent, en conservant la reliquat et maxDeliver exactement tels qu'ils étaient. concilierDeliverGroup reflète le réconcilierdreDiurableFilter, et n'est pas facultatif: le consommateur, ce changement convertit existe déjà sur le flux de l'ancienne forme, et jnats ne le fera pas joindre une simple durabilité en file d'attente. Sans le rapprochement, le premier déploiement après cela serait parti ces abonnements définitivement morts au lieu de partager - le même échec silencieux et auto-entretenu l'interréconclivité du filtre a été écrit pour. La boucle de livraison est maintenant une méthode derrière les trois points d'entrée.
· kamo-shared-library
Ajouter un abonnement éphémère, donc plus d'une dose peut servir une conversation
Un consommateur de poussée durable admet exactement UN abonné. La deuxième gousse pour lier le même nom est Le consommateur est déjà lié à un abonnement, et rien ne revient. ChatSessionAbonhonManager nomme sa durabilité après la session de discussion GUID, donc avec deux MediaService diffuse, selon lequel, si quelqu'un a lié une conversation, la posséderait silencieusement et chaque membre dont WebSocket atterrissait sur l'autre nd ne recevrait rien - pas de messages, pas de reçus lus, non événements ajoutés par un membre, pas d'erreur. Cette propriété unique est la raison pour laquelle MediaService a été épinglé à un Une réplique, et pourquoi un déploiement de celui-ci est une panne totale de discussion plutôt qu'un renversement. subscribeEphemeral() crée plutôt un consommateur anonyme. Il n'y a pas d'identité de gousse croisée pour entrer en collision over, donc chaque pod reçoit tous les messages et les fans à ses propres clients STOMP - ce que le Un courtier simple en tas l'exige. Il conserve le filtreObjet le chemin durable appris à fixer (un le filtre vide consomme l'ensemble du flux), et ajoute un seuil inactif donc un gousse qui est SIGKILLed sans désabonnement ne laisse pas éternellement son consommateur sur le flux. Pas de changement de comportement pour les appelants existants: subscribe() n'est pas affecté, et la boucle d'administration à la fois L'utilisation des chemins est maintenant une méthode de sorte qu'ils ne peuvent pas dériver. Les consommateurs éphémères ne rejouent pas les messages publiés alors que rien n'a été souscrit. Pas plus que le les mesures durables - les deux utilisent DeliverPolicy. Nouveau - donc ce n'est pas une régression.
· kamo-internal
"Que s'est-il passé?" remplit la fenêtre, donc la maximisation l'élargit
Tous les autres domaines du formulaire de rapport sont dimensionnés en fonction de son contenu. Le description est celle que quelqu'un est en fait en train d'écrire, donc il faut maintenant quelle que soit la hauteur restante, et la maximisation de la fenêtre de l'outil est donc Cela vaut la peine d'être fait. Trois parties, et toutes les trois sont nécessaires: La zone de défilement gagne une colonne de flexion interne à la hauteur: 100 %, non -hauteur: 100 %. À pleine hauteur fixe, un formulaire plus grand que la fenêtre comprimerait ses propres champs, parce que les enfants flexions se rétrécissent par défaut. Au minimum, il est exactement de pleine hauteur quand il y a de la place pour aller de l'avant. qui est la pièce que la description prend - et la pousse au-delà quand il y a non, à quel point la boîte extérieure défile et rien n'est écrasé. Le champ devient un élément flexible avec un plancher «minHeight». minRows est parti avec elle: qui entraîne TextareaAutosize, qui mesure le contenu et écrit une hauteur en ligne, et avec "flex-base: 0" il y aurait sinon être rien d'arrêter le champ s'effondrant à zéro. La zone de texte est publiée avec "hauteur: auto" --important, PAS -hauteur: 100 %. L'enveloppe esquissée étire ses enfants, de sorte que le une zone de texte le remplirait sans aide, à l'exception d'un élément flex avec un élément défini croisements ne s'étire pas, et la taille automatique lui donne une en ligne. Réglage La hauteur de retour à l'auto restitue l'étirement au lieu de le combattre. 100 % ont été essayés en premier et silencieux rien du tout: le pourcentage n'a pas contenant un bloc défini pour se résoudre contre, donc il retombe à l'auto et le champ rend à ses deux lignes intrinsèques, sans erreur nulle part à notifier. Mesuré, non supposé. Un harnais de marionnettiste construit à partir de ce composant Une sortie d'émotion donne 240px de zone de texte dans une fenêtre 720px, 444px à 940px, et un champ de plancher avec la forme faisant défiler à 430px un champ de titre toujours 40px dans les trois. Le garde engagé affirme la plutôt que la hauteur, puisque le jsaunissement ne fait pas de disposition, et il était confirmés à l'échec lorsque la règle est revenue à 100 %.

Votre univers vous attend.
Commencez gratuitement en quelques minutes. Ajoutez des produits quand vous êtes prêt. Pas de migration, pas de nouvelles connexions.
Gratuit pour toujours — aucune carte de crédit requise