mapping-tools: résultats dépendant de l'ordre d'appel #1

Closed parmentf opened this issue on 18 Oct 2021 - 8 comments

@parmentf parmentf commented on 18 Oct 2021

combine ne répond pas à toutes les sollicitations

Préalable

Détection du problème, alors qu'un serveur ezs hébergeant 3 web services a
montré des signes d'erreur (résultats instables), apparemment sans raison
apparente dans un des 3 services.

Il s'agit de vérifier que la détermination de quel service devient défaillant
dépend de l'ordre des premiers appels à ces services (a priori c'est le
dernier appelé des 3).

Précautions à prendre

Par défaut, le serveur ezs permet de distribuer les requêtes sur tous les cœurs du processeur.

Comme les commandes en question utilisent
combine,
avec le paramètre persistent à true, il sauve les résultats du file dans
une base levelDB lors de son premier appel.
Le nom de cette base dépend du PID du processus qui l'exécute (et donc se répartit dans autant de bases que de cœurs dans le processeur).

La précaution d'usage consiste donc à utiliser la variable d'environnement
EZS_CONCURRENCY pour fixer le nombre de cœurs à utiliser (et le positionner à
1).

Commande à utiliser pour lancer le serveur (en se trouvant dans le répertoire
mapping-tools):

EZS_CONCURRENCY=1 npx ezs -v -d .

Ensuite, on peut lancer les requêtes
d'examples.http
dans des ordres différents et constater lequel de ces services répond sans
trouver de correspondance (contient donc le code n/a) alors qu'il devrait en
trouver.

Tests manuels

Ordre instituts / halAuthorId / orcid

C'est l'ordre dans lequel sont écrites les requêtes.

  • instituts (738ms):
[
  {
    "id": 1,
    "value": "INEE"
  },
  {
    "id": 2,
    "value": "STIC"
  }
]
  • halAuthorId (11725ms):
[
  {
    "id": 1,
    "value": "http://www.idref.fr/190260483/id"
  },
  {
    "id": 2,
    "value": "http://www.idref.fr/165835257/id"
  },
  {
    "id": 3,
    "value": "http://www.idref.fr/182222918/id"
  }
]
  • orcid (3508ms)
[
  {
    "id": 1,
    "value": "n/a"
  },
  {
    "id": 2,
    "value": "n/a"
  },
  {
    "id": 3,
    "value": "n/a"
  }
]

Dès la première requête au troisième service, on obtient des valeurs non
conformes.

Ordre orcid / instituts / halAuthorId

  • orcid (5918ms):
[
  {
    "id": 1,
    "value": "https://orcid.org/0000-0003-1301-3305"
  },
  {
    "id": 2,
    "value": "https://orcid.org/0000-0002-6809-5654"
  },
  {
    "id": 3,
    "value": "n/a"
  }
]
  • instituts (422ms):
[
  {
    "id": 1,
    "value": "INEE"
  },
  {
    "id": 2,
    "value": "STIC"
  }
]
  • halAuthorId (7257ms):
[
  {
    "id": 1,
    "value": "n/a"
  },
  {
    "id": 2,
    "value": "n/a"
  },
  {
    "id": 3,
    "value": "n/a"
  }
]

Ordre halAuthorId / orcid / instituts

  • halAuthorId (11432ms):
[
  {
    "id": 1,
    "value": "http://www.idref.fr/190260483/id"
  },
  {
    "id": 2,
    "value": "http://www.idref.fr/165835257/id"
  },
  {
    "id": 3,
    "value": "http://www.idref.fr/182222918/id"
  }
]
  • orcid (3401ms):
[
  {
    "id": 1,
    "value": "n/a"
  },
  {
    "id": 2,
    "value": "n/a"
  },
  {
    "id": 3,
    "value": "n/a"
  }
]
  • instituts (422ms):
[
  {
    "id": 1,
    "value": "INEE"
  },
  {
    "id": 2,
    "value": "STIC"
  }
]

Ordre halAuthorId / orcid / instituts bis

Dans le doute, je réitère cet ordre (car ce n'est pas le troisième cas qui
n'était pas confirme). C'est peut-être dû à la longueur du sub-pipeline (bien
plus court pour les instituts).

Évidemment, comme à chaque fois, je relance le serveur.

  • halAuthorId (11719ms):
[
  {
    "id": 1,
    "value": "http://www.idref.fr/190260483/id"
  },
  {
    "id": 2,
    "value": "http://www.idref.fr/165835257/id"
  },
  {
    "id": 3,
    "value": "http://www.idref.fr/182222918/id"
  }
]
  • orcid (3477ms):
[
  {
    "id": 1,
    "value": "n/a"
  },
  {
    "id": 2,
    "value": "n/a"
  },
  {
    "id": 3,
    "value": "n/a"
  }
]
  • instituts (515ms):
[
  {
    "id": 1,
    "value": "INEE"
  },
  {
    "id": 2,
    "value": "STIC"
  }
]

Conclusion des tests manuels

J'ai l'impression que le service instituts n'est pas concerné, il donne toujours
les bons résultats. En tout cas, quand le cache est froid.

Je vais essayer avec uniquement les deux routes concernées par les mauvais résultats (qui sont aussi les plus longues à s'exécuter).

Tests manuels des deux routes les plus lentes

Même protocole (on relance le serveur avant chaque série de tests).

Ordre halAuthorId / orcid

route résultat temps
v1/halAuthorId/idRef/json OK 11633ms
v1/idRef/orcid/json X 3639ms

Ordre orcird / halAuthorId

route résultat temps
v1/idRef/orcid/json OK 5735ms
v1/halAuthorId/idRef/json X 6986ms

Conclusion des tests sur les deux routes les plus lentes

On constate systématiquement un temps d'exécution plus court quand le résultat
n'est pas conforme aux attentes.

À noter: quand on relance l'une ou l'autre des routes, le résultat est identique, mais arrive bien plus rapidement (visiblement le cache est utilisé).

Pour référence, les paramètres de combine:

  • halAuthorId:
[combine]
path = value
default = n/a
primer = ./halAuthorId_idRef.tsv
file = ./tsv2json.ini
persistent = true
  • orcid:
[combine]
path = value
default = n/a
primer = ./idRef_orcId.tsv
file = ./tsv2json.ini
persistent = true
  • instituts:
[combine]
path = value
default = n/a
primer = ./RNSR_InstitutsCNRS_1614.csv
file = ./instituts-cnrs.ini
persistent = true

Est-il possible que le paramètre file ait une sorte de cache lui aussi ?

Il va falloir tenter en modifiant un tsv2json.ini pour qu'il ait un nom
différent des deux autres.

Tests après renommage du script

J'ai renommé tsv2json.ini en idref2orcid.ini

Même protocole.

Ordre halAuthorId / orcid (modifié)

route résultat temps
v1/halAuthorId/idRef/json OK 11602ms
v1/idRef/orcid/json OK 5695ms

Ordre orcid (modifié) / halAuthorId

route résultat temps
v1/idRef/orcid/json OK 5855ms
v1/halAuthorId/idRef/json X 7551ms

OK pour le cache des fichiers .ini inactif par défaut.

Je vais tester avec persistent = false.

Tests après renommage du deuxième script

J'ai renommé tsv2json.ini en halauthorid2idref.ini

Même protocole.

Ordre halAuthorId (modifié) / orcid (modifié)

route résultat temps
v1/halAuthorId/idRef/json OK 10787ms
v1/idRef/orcid/json OK 5211ms

Ordre orcid (modifié) / halAuthorId (modifié)

route résultat temps
v1/idRef/orcid/json OK 5800ms
v1/halAuthorId/idRef/json OK 12155ms

Sans rien changer au paramètre persistent, mais en différenciant explicitement les files, tout se passe bien.

Il semble que la commande combine utilise un cache sur le nom du fichier passé dans le paramètre file: https://github.com/Inist-CNRS/ezs/blob/f77a2c3366ab424ab4427a61b225200a3892d685/packages/core/src/index.js#L60

le lien que tu donnes ne concerne pas combine. Si il existe un cache dans ezs, il n'est pas actif par défaut, il faut explicitement l'activer via la variable d'environnement EZS_CACHE, il sert uniquement à éviter de relire le contenu des fichiers .ini. Sinon à chaque appel les fichiers .ini sont ouverts, parser et transformer en code nodejs.

Pour le problème que tu exposes, il n'y a pas de cache, le problème est ailleurs et concerne probablement le paramètre persistent = true de combine .

As-tu les mêmes problèmes, hormis la lenteur, avec persistent = false ?

@François Parmentier François Parmentier added a commit that referenced this issue on 18 Oct 2021
3e5bda3 fix(mapping-tools): Fix issue #1 ...
@parmentf parmentf closed this issue on 18 Oct 2021

ok, merci pour cette analyse, j'en déduit, qu'il a une confusion dans les fichiers qui sont interprétés, il y a un bug quelque part ... à suivre

Oui tout-à-fait.
Je faisais appel à deux scripts différents via un chemin relatif identique, et ça pose problème.
Au minimum, il faudrait le signaler dans la doc de combine...

Quand je fais appel à la route v1/halAuthorId/idRef/json, je vois que dans le traitement de l'instruction combine, le serveur ezs fait appel findFileIn:

findFileIn([
  "/home/parmentf/prog/web-services/node_modules/@ezs",
  "/home/parmentf/prog/web-services/mapping-tools",
  "/home/parmentf/.nvm/versions/node/v14.15.4/lib/node_modules",
  "/home/parmentf/prog/web-services/mapping-tools/v1/rnsr/instituts-cnrs",
  "/home/parmentf/prog/web-services/mapping-tools/v1/rnsr/instituts-cnrs",
  "/home/parmentf/prog/web-services/mapping-tools/v1/rnsr/instituts-cnrs",
  "/home/parmentf/prog/web-services/mapping-tools/v1/halAuthorId/idRef",
  "/home/parmentf/prog/web-services/mapping-tools/v1/halAuthorId/idRef"
],
" ./halauthorid2idref.ini"
)

Je trouve étrange qu'il reste dans la liste des paths v1/rnsr/instituts-cnrs, qui n'a rien à voir avec la route que j'exécute (mais que j'ai lancée juste avant). C'est pour ça que l'ordre d'appel était important: il allait d'abord voir dans les répertoires concernés par les appels précédents.
D'où le fait que des fichiers nommés pareils, mais pas dans les mêmes répertoires puissent être pris l'un pour l'autre.

Donc, c'est la manière dont est construit ce tableau de paths qui est importante.

@parmentf parmentf referenced the issue on 3 Oct
Labels

Priority
default
Milestone
No milestone
Assignee
No one
3 participants
@parmentf @thouveni @François Parmentier