Aller au contenu
ColliePWA

10/Documentation

Le protocole filaire durable (expérimental)

Ce qui circule entre Collie et un agent durable, pour les développeurs : les routes, le hello et l'epoch, le cycle de vie d'une demande et les identifiants de requête, les transports par socket et par jeton, les limites et la règle de version, avec un lien vers WIRE.md pour les règles exactes

Expérimental. Le protocole réseau peut changer, ou la fonctionnalité peut être supprimée, dans une version mineure ultérieure. Versions et hello explicatif explique comment une modification vous parvient.

Le protocole réseau durable correspond à la manière dont Collie communique avec un agent durable. Cette page l'explique pour un développeur qui écrit un agent durable sans le SDK, ou souhaite savoir ce que fait le SDK. Les règles exactes se trouvent dans WIRE.md, et en cas de divergence avec cette page, WIRE.md fait foi. Le SDK durable gère l'ensemble pour vous.

Ce qui transite

Collie se connecte et l'agent persistant écoute, et chaque échange consiste en une requête HTTP avec un corps JSON.

L'agent persistant écoute sur un socket Unix privé, ou derrière TLS à une URL (Transports). Collie l'interroge : il n'y a pas de push, pas de WebSocket et pas de flux. Chaque chemin commence par /session/v1, qui est un nom fixe et non la version. Chaque appel sauf le premier hello transmet la version dans l'en-tête X-Collie-Session. Le corps d'une requête est un objet JSON d'au plus 64 Kio, et un corps POST vide équivaut à {}.

méthode et chemindescriptionlimite de réponse
GET /helloNom de l'agent persistant, plage de versions, époque, état de disponibilité et capacités16 Kio
GET /snapshotLa disposition : espaces de travail, onglets, panneaux avec leur état, tour et demandes ouvertes, ainsi que démarreurs. Transmet un ETag, et renvoie 304 quand rien n'a changé4 Mio
GET /pane/:id/events?after=N&epoch=ELes événements du panneau après un curseur8 Mio
POST /pane/:id/answerUne réponse à une demande16 Kio
POST /pane/:id/sendTexte pour le panneau, pour orienter le tour en cours ou attendre le suivant16 Kio
POST /pane/:id/abortArrêter le tour en cours16 Kio
POST /pane/:id/actionUn appui sur l'un des boutons de la barre du panneau16 Kio
POST /renameUn nouveau titre pour un espace de travail ou un onglet16 Kio
POST /closeFermer un panneau, un onglet ou un espace de travail16 Kio
POST /starter/:idExécuter un démarreur. La réponse nomme le nouveau panneau16 Kio
GET /conversations?after=C&limit=NLes conversations de l'agent persistant, ouvertes et fermées, de la plus récente à la plus ancienne1 Mio
GET /conversation/:id/items?after=C&limit=NLes éléments d'une conversation, du plus ancien au plus récent8 Mio
POST /reopenAfficher à nouveau une conversation fermée16 Kio

Chaque erreur est un corps JSON avec un code, comme 409 stale ou 404 no-such-pane. Tout autre chemin renvoie 404 not-found. Une réponse dépassant sa limite n'est pas lue, et un POST dont la réponse est coupée a un résultat indéterminé (Identifiants de requête).

Hello et époque

hello indique l'identité de l'agent persistant, et l'époque indique à quel démarrage de celui-ci Collie s'adresse.

champ de helloce qu'elle contient
serviceExactement collie-durable. Sans lui, Collie considère l'agent persistant comme un autre serveur et n'appelle rien d'autre
protocolLa plage de versions filaires prises en charge par l'agent persistant, { min, max }. Aujourd'hui { min: 1, max: 1 }
host.nameLe nom propre de l'agent persistant, texte d'affichage uniquement, au plus 64 octets
epochNouveau et aléatoire à chaque démarrage de l'agent persistant, au moins 128 bits, jamais réutilisé
readyFalse pendant que l'agent durable dispose ses panneaux après un démarrage
capsCe que l'agent durable peut faire, chacun étant un booléen. Une capacité absente vaut false

Collie appelle d'abord hello sans l'en-tête de version, choisit la version la plus élevée prise en charge par les deux côtés et l'envoie à chaque appel ultérieur. Tant que ready est false, chaque route sauf hello répond 503 starting, et le téléphone affiche l'agent durable comme étant en cours de démarrage. Un agent durable ne définit ready qu'une fois chaque conversation réaffichée et chaque ask ouvert soulevé à nouveau, de sorte qu'un redémarrage n'affiche jamais une disposition incomplète.

L'ETag du snapshot est "<epoch>-<rev>". rev augmente à chaque modification visible par un lecteur, donc un 304 ne coûte presque rien à l'agent durable. Une nouvelle epoch indique à Collie que l'agent durable a redémarré. Collie continue d'afficher les panneaux dont il dispose jusqu'à ce qu'il lise le nouveau snapshot. Il lit ensuite chaque panneau avec son ancien curseur et obtient la vue actuelle complète du panneau en une seule réponse.

Une lecture échouée après une lecture réussie conserve le dernier snapshot pour cette interrogation. Deux échecs consécutifs affichent l'agent durable comme injoignable. Un chemin de socket qui échoue lors du contrôle de confidentialité est immédiatement injoignable.

Asks et réponses

Un ask est une carte de question, ouverte depuis l'événement ask de l'agent durable jusqu'à son ask-closed.

étatqui le définitce que le téléphone affiche
OpenL'agent durable soulève l'ask. Le panneau affiche waiting tant qu'un ask est ouvertUne carte sous « Needs your answer », avec le nom de l'agent durable et le temps restant lorsque l'ask a expiresAt
ChangedL'agent durable modifie l'ask sur place, et son revision augmenteLa carte se redessine. Un appui sur l'ancien formulaire renvoie 409 stale, et la carte indique « This ask changed. Read it again, then tap an answer. »
TakenLe téléphone répond, et l'agent durable ferme l'ask avec by: "phone"La carte disparaît, et l'outil s'exécute ou est refusé selon l'option choisie
Decided in the durable agentL'agent durable ferme l'ask lui-même, decidedBy: "program". L'interruption du tour compteUne ligne dans Chat commençant par « Decided in the durable agent », avec le titre de l'ask
Timed outL'horloge dépasse expiresAt, decidedBy: "timeout"Une ligne dans Chat commençant par « Timed out before an answer », avec le titre de l'ask

Un appui survenant après la décision renvoie 409 decided avec le premier résultat, et rien ne s'exécute. La carte indique ensuite qui a décidé en premier : « Decided in the durable agent. », « Timed out before an answer. » ou, après un autre appui, « Already answered. This card goes away on the next update. » Un ask que l'agent durable ne connaît plus renvoie 200 too-late. La carte indique alors « Not taken. The question may show again in a moment. », car après un redémarrage, l'agent durable peut le soulever à nouveau sous le même identifiant.

règlepourquoi
L'identifiant de l'ask est un hash de l'identifiant du panneau et de l'identifiant de l'appel d'outilLe même appel d'outil soulevé après un redémarrage a le même identifiant, de sorte qu'une réponse envoyée à travers le redémarrage aboutit
Une carte permission est construite à partir du nom de l'outil et de ses arguments, jamais à partir des mots du modèleUn modèle qui veut un oui décrirait l'appel de manière favorable
Un agent durable derrière TLS ne doit proposer aucun allow-alwaysLe token est l'unique verrou, donc une réponse de quiconque le détient autoriserait chaque appel ultérieur
Le téléphone ne propose aucun allow-always sur une carte dont les mots ont été coupés ou nettoyés, ou qui ne nomme aucun outilL'utilisateur ne peut pas voir ce que couvre l'autorisation
expiresAt est au format ISO 8601 avec fuseau horaireAu-delà, la demande est tranchée par timeout, et un instantané ne l'affiche plus comme ouverte
L'agent durable conserve le résultat d'au moins ses 500 dernières demandes tranchées par voletUn appui tardif reçoit decided et le premier résultat, pas un simple too-late

Une demande est de l'un des quatre types suivants : permission, choice, text ou form. Chacun a sa propre structure de réponse, répertoriée avec le Questions du SDK.

Identifiants de requête

Chaque action provenant du téléphone possède un identifiant de requête, afin de ne s'exécuter qu'une seule fois au maximum.

Le téléphone génère un identifiant de requête par intention, et Collie écrit son propre accusé de réception avant de transmettre l'identifiant. L'agent durable conserve au moins les 500 derniers identifiants de son époque. Une répétition d'un identifiant terminé reçoit à nouveau la première réponse avec replayed: true et n'exécute rien. Le même identifiant avec une charge utile différente reçoit 409 request-id-reused.

Collie ne réessaie jamais un POST de lui-même. Un POST qui expire, perd sa connexion ou reçoit un 5xx a un résultat inconnu. Pour une réponse, la carte indique alors « Not sure the answer arrived. Try again sends it once more. », et Try again renvoie le même identifiant de requête, afin que la mémoire de l'agent durable réponde à une répétition.

Une nouvelle tentative qui trouve la demande fermée ou le tour déplacé ne peut pas savoir si le premier essai a abouti. Collie répond alors au téléphone « maybe applied », la carte indique « May already be applied. Check the chat. », et l'action n'est jamais envoyée une troisième fois.

Transports

Un agent durable utilise l'un des deux transports : un socket privé sur la machine de Collie, ou TLS avec un jeton.

Les octets sont les mêmes sur les deux : les routes, les corps, l'en-tête de version, l'ETag et les codes d'erreur. Seule la liste des personnes autorisées à joindre l'agent durable diffère.

via le socketla règle
CheminAbsolu, d'au plus 103 octets. Les deux côtés le lisent depuis COLLIE_DURABLE_SOCKET
ModesLe socket est en mode 0600, dans un dossier en mode 0700. L'agent durable supprime un fichier socket obsolète avant d'écouter
Le parcours du cheminAvant chaque connexion, Collie vérifie chaque segment du chemin avec lstat. Aucun segment n'est un lien symbolique. Le dossier du socket vous appartient avec le mode 0700. Aucun dossier parent n'est accessible en écriture par le groupe ou les autres, sauf s'il possède le sticky bit comme /tmp. Le socket vous appartient, sans droit pour le groupe ou les autres
Un parcours en échecCollie ne se connecte pas et affiche l'agent durable comme injoignable avec socket-not-private et le segment en cause
TokenAucune. Le socket privé sert de barrière
Qui peut agirTout processus de votre utilisateur. L'agent durable peut refuser ses propres descendants avec 403 caller-refused
Délais d'expiration1000 ms pour hello, snapshot et events. 3000 ms pour une réponse, un envoi, un arrêt, une action, un renommage ou une fermeture. 30000 ms pour un démarrage
Fréquence des requêtes de CollieToutes les 1 s lorsqu'un téléphone observe, sinon toutes les 3 s. Un agent durable arrêté est interrogé une fois par intervalle de scrutation
SystèmesLinux et macOS. Windows n'a pas de transport par socket
via TLSla règle
URLhttps://, ou http://127.0.0.1:<port> ou http://localhost:<port> pour un test local. 2048 octets au maximum, aucun nom d'utilisateur ni mot de passe, aucune requête, aucun fragment. Collie y ajoute /session/v1
TokenAu moins 32 octets, en ASCII imprimable sans espace. Collie envoie Authorization: Bearer <token> à chaque requête, hello inclus
La vérification de l'agent durableLe token d'abord, avant la version, hello et ready, comparé en temps constant. Un token manquant ou incorrect reçoit un simple 401 { "code": "unauthorized" } et rien d'autre
RedirectionsCollie n'en suit aucune. Un 3xx est transmis comme statut, afin que le token n'atteigne jamais un autre hôte
ETagUn proxy qui compresse une réponse peut affaiblir le tag en W/"<epoch>-<rev>". Les deux côtés le comparent en retirant le W/
Un refusUn 401 ou un 403 affiche l'agent durable comme injoignable avec token-refused
Délais d'expiration5000 ms pour chaque lecture et écriture, car un agent durable en veille peut se réveiller à froid. 30000 ms pour un starter
Fréquence des requêtes de CollieToutes les 2 s lorsqu'un téléphone observe, sinon toutes les 10 s. Un agent durable arrêté ou refusé est interrogé au maximum une fois toutes les 10 s

Chaque timeout est une échéance pour l'ensemble de l'échange, de la connexion au dernier octet. Via TLS, chaque scrutation est une requête que votre hébergeur peut facturer, 304 inclus.

Limites

Collie coupe ou refuse tout ce qui dépasse ces limites, ainsi un agent durable qui reste en deçà ne perd rien.

quoilimite
Espaces de travail par snapshot64
Onglets par snapshot256
Panneaux par snapshot256
Demandes ouvertes par panneau50, les plus anciennes d'abord
Options d'un permission6
Options d'un choice, et d'un champ de choix8
Champs d'un form6
Starters par snapshot50
Boutons de ceinture par panneau4, un libellé de 16 caractères
Un identifiant1 à 128 octets, aucun caractère de contrôle, aucun espace, aucun parmi /, ? ou #
Un corps de requête64 Kio, sinon 413 too-large
Réponseshello 16 Kio, snapshot 4 Mio, events 8 Mio, conversations 1 Mio, items 8 Mio, un POST 16 Kio
Événements par réponse1000. Un lecteur qui a pris du retard reçoit la vue actuelle, au maximum les 2000 éléments les plus récents
Texte d'un élément user, reply, thinking ou notice64 Kio
Texte d'un élément markdown ou code32 Kio
Texte envoyé par le téléphone32 Kio
Un élément linkhttps:// uniquement, au maximum 2048 caractères
Une page d'historique100 conversations, ou 1000 éléments
Un curseur d'historique512 octets d'ASCII imprimable, aucun espace

Une chaîne dépassant sa limite est tronquée, et ses caractères de contrôle et invisibles sont supprimés. Une liste dépassant sa limite conserve ses premiers éléments. Une page d'historique dépassant sa limite n'est pas lue du tout.

Versions et hello explicatif

Il existe aujourd'hui une seule version de protocole, 1, et Collie utilise 1..1.

À la sortie de la version 2, Collie acceptera la version 1 pendant une version mineure supplémentaire, puis l'abandonnera à la suivante. Un lecteur ignore les champs, les types d'événements, les sortes d'éléments ou les codes qu'il ne connaît pas. Un champ ajouté au sein de la version 1, tel que expiresAt ou decidedBy, est facultatif. Un nouveau champ obligatoire, une nouvelle signification pour un ancien champ, ou un champ supprimé nécessite une nouvelle version.

Une demande d'une sorte inconnue du téléphone s'affiche comme une demande à laquelle il ne peut pas répondre depuis le téléphone, sans boutons.

Lorsque les deux plages ne se recoupent pas, Collie ne lit plus rien de l'agent durable. Une fois par époque de l'agent durable, il envoie un hello supplémentaire, cette fois avec sa propre version, pour que l'agent durable puisse consigner l'incompatibilité de son côté. L'agent durable répond 409 incompatible avec un refusal qui indique les deux plages. C'est le hello explicatif.

Collie écrit une ligne dans ses journaux pour chaque plage qu'il refuse, et collie doctor affiche les deux plages. L'écran d'accueil de l'agent durable sur le téléphone affiche la même phrase, par exemple « The durable agent speaks wire v2, this Collie speaks v1. Update Collie, or the agent's SDK. ». Mettez à jour le composant le plus ancien.

Où trouver les règles exactes

WIRE.md constitue le contrat, avec chaque format, code et règle.

Les décisions associées sont consignées dans le dépôt :

enregistrementce qu'il décide
ADR 0099Un agent durable est un multiplexeur sans écran
ADR 0100Une demande circule sous forme de données et reçoit une réponse par identifiant
ADR 0101Send et stop nomment le tour vu par le téléphone
ADR 0102Les lanceurs sont des lignes sur la page New
ADR 0103Les deux transports
ADR 0104Un agent durable est une session, et la sortie
ADR 0105Le SDK est un paquet npm

Modifier cette page sur GitHub

The rest of the documentation