10
votes

Les API reposantes doivent être apatrides, mais qu'en est-il de la concurrence?

Je suis curieux de savoir comment je résolvez le problème de la concurrence pour une API reposante. Plus spécifiquement, j'ai une collection d'objets nécessitant un examen manuel et une mise à jour, par exemple. un certain nombre de lignes nécessitant une colonne mises à jour à la main; Toutefois, si j'ouvre l'API à un certain nombre de clients, ils saisiront tous ces éléments du haut en bas, de nombreux utilisateurs rempliront la colonne de la même ligne en même temps. Je préférerais ne pas avoir de collisions et de manière simple, de manière remarquée, consiste simplement à jeter des objets dans une file d'attente sur le service et à les éliminer en tant que personnes les demandes.

Quelle est la version apatride de cela? Hachage par adresse IP ou saisissez au hasard des lignes basées sur l'ID?

:: mise à jour ::

"HRM, il faut donc simplement être apatride du point de vue du client?

Cela a certainement beaucoup de sens. Je lisais juste un article (IBM.com/developerworks/webservices/library/ws-resful) sur les API reposantes et après avoir rencontré le peu de pagination, j'étais inquiet que ma file d'attente assez importante était similaire à l'incrémentation d'une page, mais Ils sont en fait assez différents, car "Page suivante" est relative du côté du client, tandis que "pop" est toujours apatride pour le client: peu importe ce qui a été sauté auparavant.

Merci d'avoir refusé la tête! "-Me


3 commentaires

Je ne vois pas vraiment le problème / la question ici. Les API reposantes peuvent être - et IME presque toujours - soutenu par des serveurs d'état. Pourriez-vous clarifier le problème que vous essayez de résoudre?


Les balises électroniques peuvent être utilisées fournissent une concurrence


HRM, il faut donc simplement être apatride du point de vue du client? Cela a certainement beaucoup de sens. J'étais juste en train de lire un article ( ibm.com/developerworks/webservices/library/ ws-reposondre ) sur les API reposantes et après avoir rencontré le peu de pagination, j'étais inquiet que ma file d'attente assez stimulante était similaire à l'incrémentation d'une page, mais ils sont en réalité très différents comme «Page suivante» est relatif. du côté du client, tandis que "pop" est toujours apatride pour le client. Peu importe ce qui a été sauté auparavant. Merci d'avoir refusé la tête!


3 Réponses :


5
votes

Il y a deux approches de base que vous pouvez prendre:

  1. va complètement apatride et adopte une stratégie "Dernière demande WINS". Aussi étrange que cela puisse sonner, il est probable que la solution la solution la plus propre en termes de prévisibilité, d'évolutivité, de complexité de code et de mise en œuvre sur les côtés du client et du serveur. Il y a aussi beaucoup de priorité pour cela: regardez comment des sites tels que Google Paginate via des requêtes à l'aide d'un Démarrer = 10 pour la page 2, Démarrer = 20 pour la page 3, etc. < / p>

    Vous trouverez peut-être que le contenu change dans les pages lorsque vous naviguez entre eux, mais donc quoi? Vous obtenez toujours les dernières informations et Google peut gérer vos demandes sur l'un de leurs nombreux serveurs sans avoir à trouver vos informations de session pour déterminer votre dernier contexte de requête.

    Le plus gros avantage de cette approche est la simplicité de la mise en œuvre de votre serveur. Chaque demande peut simplement passer à travers la couche de données à l'arrière, et elle est absolument mûr pour la mise en cache au niveau HTTP (via des balises électroniques ou des en-têtes de dernière modification) et le côté serveur (en utilisant quelque chose comme Memcache, pour exemple).

  2. GO STALLIVE, et déterminez un moyen de faire sortir vos serveurs une sorte de verrouillage ou de jeton par client pour chaque "session" de l'API. Ce sera comme essayer de combattre la marée de l'océan avec un bâton, car vous finirez par défaut et frustré.

    Comment identifierez-vous les clients? Clés de session? Adresse IP? Descripteur de fichier pour la prise qu'ils montrent (bonne chance avec cela si vous utilisez un transport comme http où la connexion peut être fermée entre les demandes ...)?)? Les détails que vous choisissez pour cela devront être persistés du côté du serveur, ou vous devrez utiliser une ancienne fonction de session collante de votre serveur d'applications (et si oui, le ciel aidait votre client si le serveur qu'ils utilisent diminue. mi-session).

    Comment allez-vous gérer des clients API qui disparaissent sans scrupule? Souhaitez-vous faire demi-t-on automatiquement leur session en cas de nettoyage de filet d'inactivité? C'est plus de code, plus de complexité et plus d'endroits pour les bugs à cacher. Qu'en est-il des clients API qui reviennent d'un temps d'inactivité long et tentent de réutiliser une serrure expirée, comment les applications client doivent-elles être conçues pour gérer cette situation?

    Je pourrais continuer, mais j'espère que vous pouvez voir mon point. Allez avec l'option 1 et allez les apatrides. Sinon, vous finirez par essayer de suivre l'état du client sur le côté serveur. et la seule chose qui devrait suivre l'état d'un client est le client lui-même.


5 commentaires

Je ne pense pas que l'acceptation de changements de contenu lors de la navigation sur les pages de résultats est le mode de pensée unique et unique. Vous pouvez voir des entrées doubles - OK (et le client pourrait manquer cela quand même), mais vous pouvez également manquer des entrées totalement dus à des déménagements dans la portée des pages passées / précédentes - pas bien. Pour les résultats de la recherche de Google qui peuvent ne pas avoir d'importance, mais dans d'autres contextes, cela peut.


Comme une alternative, on peut récupérer "Tous les identifiants" sur le client (OK, pour les résultats de la recherche Google qui n'est pas réalisable la plupart du temps) et parcourez cette page de liste par page, chargez plus de contenu lorsque vous atteignez la page Définition de cet identifiant Sub. -ensemble. Les mauvaises nouvelles sont que le problème revient juste autour du coin: il peut y avoir des articles que supportés (qui ne peuvent plus être chargés - doivent être attrapés d'une manière ou d'une autre), et il peut y avoir de nouveaux éléments supplémentaires que vous ne voyez pas par Parcourir votre ensemble de résultats actuel. Ainsi, la question est la suivante: qu'est-ce qui est plus important pour vous?


Si vous ne vous souciez pas de manquer ou de doubler des éléments lors de la navigation de votre page de résultat par page, vous allez bien, vous allez bien, vous allez bien, vous allez bien, vous allez bien mettre le numéro de page ou la plage d'index dans l'URL en tant que paramètre - chargé du service avec le chargement et le lancer loin de tous les articles qui auraient été placés sur n'importe quelle page auparavant. (Comment google gérer cela? Quelqu'un a essayé une requête absurde et spécifiant initialement un numéro de page élevé, comme "Query = millionnaire et page = 59786"?)


Si, d'autre part, vous voulez des ensembles de résultats stables lors de la navigation de page tout en fournissant des données de détail frais, vous devez mettre en cache au moins l'identifiant de résultat de la requête (si possible) et passer à travers cet ensemble lors de la navigation de pages. Vous devrez traiter entre-temps des articles supprimés cependant, et vous ne verrez pas d'éléments ajoutés avant d'atteindre la page où ils "auraient comparu quand la requête a été posée plus tard". - Il y a un certain prix à payer de toute façon, comme il semble que cela semble.


A la manière dont cette approche devrait être considérable comme "reposante" aussi, car il n'y a pas d'état géré du côté serveur. Si vous considérez que les identifiants d'élément équivalent aux hyperliens pointant vers un emplacement de ressource à un seul élément, il s'agit également d'HyperMedia-style (et serait parfaitement parfait, si l'ensemble ID est en fait un jeu de localisation de ressources ID, mais plus de bande passante et la mémoire côté client est nécessaire).