Comment écrire un module Redis en Zig

Comment écrire un module Redis en Zig

Mise à jour (9 mai 2019) : Modification du code pour tenir compte de la nouvelle version de Zig version 0.4.0

Tout le monde a une instance Redis quelque part dans sa pile ou, à tout le moins, connaît Redis. Cependant, tout le monde ne sait pas que Redis prend en charge les modules : des extensions personnalisées qui ajoutent de nouvelles commandes, types de données et fonctionnalités à une base de données Redis.

Besoin d’une nouvelle structure de données ? Recherche en texte intégral? Vous souhaitez stocker des données graphiques dans Redis ?

Tout cela est déjà possible avec modules existants qui sont activement développés par la communauté Redis.

Si vous avez un cas d’utilisation spécifique qui n’est pas encore couvert et que vous avez besoin des performances offertes par Redis, vous pourriez être intéressé à apprendre à écrire un module.

La manière par défaut de construire un module consiste à utiliser C et à le compiler en tant que bibliothèque dynamique partagée.

Si vous connaissez le C, alors tout va bien, mais si vous ne le connaissez pas, la mise en place d’un tout nouveau projet en C peut sembler un peu écrasante. Il est facile d’oublier un petit détail sur le processus de compilation et de se retrouver avec un binaire qui segfault sans raison apparente.

Cela peut devenir encore plus frustrant lorsque vous devez gérer une compilation multiplateforme, par exemple lorsque vous développez sur macOS ou Windows et que vous avez l’intention de déployer sur Linux.

Présentation de Zig

Zig est un tout nouveau langage développé par Andrew Kelley qui met l’accent sur l’apport d’un confort moderne à la manière C d’écrire des programmes. Le résultat est un langage qui vous permet de créer des binaires entièrement compatibles C ABI tout en ayant accès à des fonctionnalités de langage telles que la vérification avancée des erreurs par le compilateur, de meilleures fonctionnalités de métaprogrammation, des génériques, des options, des types d’erreurs, etc.

Comment les modules interagissent avec Redis

Les modules Redis sont des fichiers objets qui peuvent être chargés dynamiquement par Redis lors de l’exécution. Un module attend l’accès à quelques fonctions exposées par Redis qui lui permettent de fonctionner dans l’écosystème Redis. La seule interface que le module doit implémenter est une fonction appelée RedisModule_OnLoad()qui sert généralement à enregistrer dans Redis toutes les nouvelles commandes que propose le module.

Cela signifie que vous pouvez utiliser n’importe quel langage qui peut être compilé dans une bibliothèque dynamique compatible C, et Zig le rend particulièrement facile tout en vous permettant d’utiliser des abstractions plus modernes dans votre code privé.

Écrivons un module très simple appelé module de test qui met en œuvre une test.hello commande, qui n’envoie que “Hello World!” au client lorsqu’il est appelé.

Modules d’écriture – The C Way

En C, la façon la plus simple d’écrire un module Redis est de télécharger une copie du redismodule.h fichier d’en-tête de Dépôt officiel de Redis (branche instable)incluez-le au début de votre code et écrivez le module.

Un fichier d’en-tête est la manière C de décrire l’interface d’un autre morceau de code qui ne fera pas réellement partie de la phase de compilation, permettant au compilateur de savoir si des symboles non implémentés sont utilisés de manière incorrecte.

Voici à quoi ressemble notre code de module en C :

Outre l’importation du fichier d’en-tête, le script ne contient que deux implémentations de fonction : HelloWorld_Command() et RedisModule_OnLoad().

Comme indiqué précédemment, RedisModule_OnLoad() est invoqué par Redis lors du chargement du module, tandis que HelloWorld_Command() est notre exemple de commande

Maintenant que nous avons écrit un module HelloWorld simple en C, regardons comment pouvons-nous faire cela en Zig.

Modules d’écriture – The Zig Way

Avant de commencer à écrire en Zig, vous vous demandez peut-être comment importer toutes les définitions d’un fichier d’en-tête C si vous n’écrivez pas en C ?

Cela semble déjà un gros obstacle, mais Zig fait de l’intégration avec les projets C une priorité et offre donc deux façons d’importer rapidement un fichier d’en-tête.

La méthode la plus rapide consiste simplement à appeler @cInclude()qui permet d’importer directement un fichier d’en-tête, tandis que le second consiste à utiliser une commande du compilateur pour traduire le code C en Zig (ce qui est ce que @cInclude() fait sous le capot).

Bien qu’immédiate, dans notre cas, la première option n’est pas la meilleure pour plusieurs raisons, la plus importante étant que Zig est un langage sûr, et la traduction automatique du fichier d’en-tête fait en sorte que Zig suppose que chaque pointeur peut être nul, et nécessite donc à l’utilisateur de vérifier explicitement avant qu’une opération puisse être effectuée.

Valeurs nulles dans Zig

Selon plusieurs, les pointeurs nuls sont l’une des pires choses qui soient arrivées à l’informatique.

Dans Zig, les valeurs qui peuvent être nulles sont enveloppées dans un type de conteneur générique appelé Optionnel.

Les types optionnels deviennent très répandus : Rapide, Kotlin, Rouillertous les ont, pour n’en nommer que quelques-uns.

Lorsque vous avez une valeur optionnelle (que ce soit un pointeur ou autre), avant de pouvoir y accéder, vous devez déballer ce. Cela applique des vérifications explicites sur toute valeur nulle potentielle sans avoir à vérifier sans discernement ou risquer une exception non gérée.

Malheureusement, null est une valeur valide pour les pointeurs en C, et à cause de cela, il n’y a aucun moyen de spécifier si un pointeur est autorisé à être nul ou non. Cela signifie que lors de l’importation de signatures de fonction à partir d’un fichier d’en-tête, chaque argument formel qui est un pointeur sera traduit en un pointeur facultatif Zig, ce qui est le choix correct et sûr, mais rend l’utilisation des symboles importés inutilement verbeux, si vous savoir avec certitude qu’un pointeur donné ne sera jamais nul.

Pour vous montrer explicitement, c’est ce que HelloWorld_Command() ressemblerait lors de l’importation directe du fichier d’en-tête :

S’assurer qu’on ne cherche pas à déréférencer un pointeur nul c’est très bien, mais c’est un peu verbeux si on sait qu’un pointeur ne sera jamais nul, comme c’est le cas avec les arguments formels des commandes Redis par exemple.

La solution est d’utiliser :

$ zig ​​translate-c redismodule.h

Cela obtiendra un fichier Zig équivalent au fichier d’en-tête et modifiera quelques signatures de type pour nous épargner un déballage optionnel inutile.

Pour vous faciliter la tâche, vous pouvez télécharger une copie déjà nettoyée de redismodule.zig (compatible avec Zig 0.4.0 et Redis 5.0). Sachez simplement que ce n’est pas officiellement pris en charge et que vous devrez peut-être vous salir les mains au cas où quelque chose ne fonctionnerait pas.

Voici à quoi ressemble le module lorsqu’il est écrit en Zig :

Comme vous pouvez le constater, la traduction est très simple, la principale différence étant que les symboles importés sont stockés dans la constante redis.

Une autre chose à noter est que C a souvent une interopérabilité difficile avec d’autres langages en raison d’incohérences dans la façon dont les chaînes sont représentées en mémoire. En C, les chaînes sont des pointeurs vers des tableaux d’octets à terminaison nulle, tandis que d’autres langages ont une variété de représentations différentes. Zig lui-même n’utilise pas de chaînes de style C, mais il est facile de les produire en préfixant `c` à une chaîne littérale, comme vous pouvez le voir dans notre code Zig.

Cet exemple simple montre que le code C a une traduction généralement simple en Zig, mais ne pensez pas que vous vous retrouvez ensuite avec un “C avec des étapes supplémentaires”. Il existe de nombreuses fonctionnalités que vous apprécierez sûrement lorsque vous passerez à l’écriture d’un véritable module qui déplace les données.

Consultez le documentation officielle Zig pour une liste complète des fonctionnalités.

Construire un module Zig

Zig a une commande de construction dédiée pour les bibliothèques partagées :

$ zig ​​build-lib -module dynamique.zig

Si vous avez besoin d’effectuer une compilation croisée pour Linux 64 bits :

$ zig ​​build-lib -module dynamique.zig –target-os linux –target-arch x86_64

Pour essayer votre module, vous pouvez utiliser les commandes suivantes dans redis-cli ou via le Interface graphique d’entreprise Redis:

> MODULE LOAD /path/to/module.so.0 (ou libmodule.0.0.0.dylib sur macOS)

D’ACCORD

> test.bonjour

Bonjour le monde!

En conclusion

Nous avons vu comment Zig fait de l’intégration avec l’écosystème C une expérience raisonnablement agréable. Vous avez d’excellents raccourcis tels que @cInclude() et c “Hello World” ainsi que des trappes d’échappement très pratiques lorsque vous avez besoin de plus de contrôle, comme avec la commande du compilateur translate-c.

Le résultat est un langage qui vous donne plus de garanties de sécurité et un processus de construction extrêmement simple qui prend même en charge la compilation croisée en une seule commande.

La seule chose qui reste à savoir maintenant, c’est ce que vous pouvez réellement faire à l’intérieur d’un module Redis.

Le site officiel contient un liste des modules publiés et le référence complète de l’API du module.

Si vous souhaitez partager un module Redis écrit par vous et que vous pensez que la communauté apprécierait, envoyez une pull request à antirez/redis-doc pour qu’il soit ajouté à la liste.

Bon piratage !

Development Source

Related Posts

RLEC 4.2.1 apporte des contrôles granulaires à la haute disponibilité et aux performances

RLEC 4.2.1 apporte des contrôles granulaires à la haute disponibilité et aux performances

Comment HolidayMe utilise Redis Enterprise comme base de données principale

Comment HolidayMe utilise Redis Enterprise comme base de données principale

Annonce de RedisGears 1.0 : un moteur sans serveur pour Redis

Annonce de RedisGears 1.0 : un moteur sans serveur pour Redis

Clés Redis dans la RAM |  Redis

Clés Redis dans la RAM | Redis

No Comment

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *