Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZéPS-Core V2 #7

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open

ZéPS-Core V2 #7

wants to merge 13 commits into from

Conversation

AmauryCarrade
Copy link
Member

@AmauryCarrade AmauryCarrade commented Mar 12, 2018

Rewrites everything in Rust with a completely new data structure.

This also brings multiple-universes support.

Related to #4.

* NEW: Updated dependencies
* NEW: Added basic integration test and fixture
* NEW: Separated the main application's logic (zeps-core) to a library
  project (zeps)
* NEW: Added config::read_world() method.
* NEW: Added data::World::stations() and data::Network::stations()
  methods, which return optimized iterators.
* BUG: Coordinates are now signed integers
* NEW: Renamed the World structures to Universe
* NEW: Add some public methods so the compiler won't complain about
  unused fields
* NEW: Added error management (using the failure crate)
* NEW: Added configuration errors
* NEW: Added missing NetworkConnection structure
* NEW: Added Station.is_hidden field
@FlorianCassayre
Copy link
Member

Semi-HS : J'avais eu l'idée de le porter en Scala puis de réécrire le serveur web avec le framework play (en Scala également), l'idée étant d'utiliser le calculateur directement en tant que librairie. Outre les gains de performance et la meilleure maintenabilité, il serait possible de programmer des tâches d'arrière-plan pour précalculer tous les chemins.
Je sais pertinemment que cette solution n'est pas forcément pratique pour vous mais j'ai tout de même envie de le tenter de mon côté.

@AmauryCarrade
Copy link
Member Author

AmauryCarrade commented Mar 12, 2018

En terme de web on comptais utiliser Rocket, un serveur web en Rust, histoire d'avoir un tout cohérent.

l'idée étant d'utiliser le calculateur directement en tant que librairie

Nous partagions une idée similaire, mais en Rust du coup. D'ailleurs le code Rust est déjà structuré ainsi.

Outre les gains de performance et la meilleure maintenabilité, il serait possible de programmer des tâches d'arrière-plan pour précalculer tous les chemins.

En terme de performances et maintenabilité, Rust est pas mal aussi :) (sans critiquer Scala, j'ai entendu de très bonnes critiques à son égard également).

Il y a beaucoup de chemins, mais en effet pré-calculer au moins les chemins les plus courants pourrait être un plus. Je ne sais pas trop ce qui peut être fait de ce côté en Rust, mais vu l'orientation très calcul massivement parallèle du langage, je serais surpris que ce ne soit pas possible.

In fine, pas mal d'idées partagées si ce n'est le choix de la technologie…

On a déjà pas mal avancé sur la version en Rust, bien que l'on ait un peu traîné j'avoue, ainsi que posé la structure de l'API exposée V2 que l'on voulait — que je vais recopier de Slack ici-même si tu es curieux de donner ton avis.

Du coup ça m'embête un peu de te couper l'herbe sous le pied… Après, je ne t'empêche pas de le tenter malgré tout ! Si tu lis les mêmes données que nous et expose la même API, cela pourrait même faire deux implémentations intercompatibles.

Sens-toi libre de revenir sur Slack si tu veux en discuter, sois-dit en passant.


À titre indicatif donc, mais ça a sa place dans cette PR, la structure d'API REST que nous avions imaginé :

/universes              Retourne la liste des univers existants (Vessinque, V6…).

/universes/<universe>   Retourne des informations basiques sur l'univers donné
                        (ID, nom), ainsi que des statistiques générales sur
                        l'univers (utilisées par la page de statistique du GUI).

/universes/<universe>/networks
                        Retourne la liste des réseaux dans l'univers donné.

/universes/<universe>/networks/<network>
                        Retourne des informations de base sur le réseau donné.

/universes/<universe>/networks/<network>/lines
                        Retourne la liste des lignes dans le réseau donné.

/universes/<universe>/networks/<network>/lines/<line>
                        Retourne la liste des stations dans la ligne donnée du
                        réseau donné.

/universes/<universe>/networks/<network>/stations
                        Retourne la liste des stations dans le réseau donné de
                        l'univers.

/universes/<universe>/networks/<network>/stations/<station>
                        Retourne les informations détaillées sur une station,
                        ainsi que les stations connectées et la ligne.

/universes/<universe>/networks-connections
                        Retourne des informations sur les interconnexions entre
                        les différents réseaux de l'univers.

/universes/<universe>/full-details
                        Retourne toutes les informations sur le réseau de
                        l'univers ayant le-dit nom.
                        En soit, c'est limite le JSON brut qu'est retourné,
                        mais avec les valeurs par défaut “étendues”, donc il
                        faut le reconstruire — les utilisateurs de l'API n'ont
                        pas à réfléchir sur les valeurs par défaut, tout doit
                        être explicite.

/universes/<universe>/path/<from>/<to>?options
                        Calcule l'itinéraire entre l'origine et la destination
                        (où from et to sont des noms de code des stations dans
                        l'univers donné).

/locate/<world>/<coordinates>
                        Localise et retourne l'univers, le réseau, et la station,
                        les plus proches des coordonnées données.

/reload-universes       Recharge les fichiers de réseau sans redémarrer le moteur.
                        Permet de recharger via une interface web ou via le plugin
                        qui gère les routes.
                        Une forme d'authentification serait souhaitable (ça peut se
                        limiter à des clefs dans un fichier de configuration).

/version                Retourne un numéro de version et une clef unique qui change
                        lorsque la définition des réseaux change d'une façon ou d'une
                        autre (typiquement, un SHA26 de la concaténation des fichiers
                        JSON de définition des réseaux plus de la version du moteur).
                        Utilisé pour invalider un éventuel cache. Appelé donc souvent :
                        mettre ça en… cache serait judicieux.

On accepte les critiques bien évidemment :) .

Quant à la structure JSON que l'on imaginais, elle est toujours là sans avoir trop bougé depuis.

@FlorianCassayre
Copy link
Member

Ah, bon, si vous refaites aussi le backend en rust dans ce cas-là j'approuve.

@AmauryCarrade
Copy link
Member Author

AmauryCarrade commented Mar 12, 2018

(J'ai légèrement modifié ma réponse précédente en ajoutant des trucs, si tu as lu trop tôt, cf. les citations.)

Oui, l'objectif est bien de refaire tout le cœur du ZéPS en Rust, pour avoir un programme 100% Rust, on ne parle pas que de l'interface web.

@FlorianCassayre
Copy link
Member

Vu, et :

pour avoir un programme 100% Rust

Je me permets d'objecter cette affirmation (:>), contrairement à Scala il ne me semble pas qu'il existe de synthétiseur Javascript en Rust. (aussi il existe un connecteur Scala.js pour la librairie leaflet)

@AmauryCarrade
Copy link
Member Author

AmauryCarrade commented Mar 12, 2018

Je me permets d'objecter cette affirmation (:>), contrairement à Scala il ne me semble pas qu'il existe de synthétiseur Javascript en Rust.

Objecte, objecte, mais ne parle pas trop vite :-° . Par contre certes, on est loin du niveau de stabilité de Scala à ce niveau (c'est de l'alpha, et répondre à Scala avec RJS est un peu de la mauvaise foi de ma part :p ). Et il n'y a pas de connecteur vers Leaflet à ma connaissance.

Par contre, je ne vois pas en quoi c'est un soucis à ce niveau ? Au cas où je parle bien du backend uniquement, le ZéPS GUI reste en dehors de cela a priori. Il est prévu qu'il soit en Python, bien que je pourrais le tenter en Rust aussi parce que pourquoi pas.

En soit il y aurait une partie non-Rust, certes, car on pensait ajouter une documentation de l'API en page d'accueil (c'est mieux qu'une erreur 404 ^^) avec Swagger, qu'est en HTML+JS+CSS (classique). Mais à part ça…

Sauf si j'ai complètement mal compris ce que tu voulais dire et dans ce cas au temps pour moi.

J'admets qu'en disant « On ne parle pas que de l'interface web » j'étais un peu ambigü — je parlais de l'interface entre le web et le cœur, exposant ce dernier sous la forme d'une API REST. Pas du GUI pour le grand public.

* NEW: lines are now imported and validated (e.g. for valid stations in them).
* NEW: instead of a HashMap<String, Station>, stations of a network are now in a HashMap<String, Rc<Station>>.
* NEW: updated fixture to validate.
* NEW: the `subname` key in the stations objects is now `sub_name`.
* NEW: network explicit connections (in networks_connections.connections) are loaded and the stations are checked in their respective networks.

What could be improved:
- error message on unknown station, to specify the context and the network.
* NEW: added tests to check if the universes are correctly loaded and parsed, and to check if errors are correctly handled.
* OPT: made a condition more “rustic”.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants