Il est intéressant de créer un service dans le cas d'une application web ou d'un processus qui doit tourner perpétuellement. Pour commencer, il faut inclure le package service kardianos/service.
import "bitbucket.org/kardianos/service"
Il faut ensuite appliquer ce modèle qui permet de contrôler le service (installation, démarrage...) ainsi que d'initialiser quelques variables comme celle de la description dans le service manager.
var logSrv service.Logger var name = "goServerView" var displayName = "Go Server View" var desc = "Mini webserver allowing to share informations (files, folders, etc...)" // main runs the program as a service or as a command line tool. // Several verbs allows you to install, start, stop or remove the service. // "run" verb allows you to run the program as a command line tool. // e.g. "goServerView install" installs the service // e.g. "goServerView run" starts the program from the console (blocking) func main() { s, err := service.NewService(name, displayName, desc) if err != nil { fmt.Printf("%s unable to start: %s", displayName, err) return } logSrv = s if len(os.Args) > 1 { var err error verb := os.Args[1] switch verb { case "install": err = s.Install() if err != nil { fmt.Printf("Failed to install: %s\n", err) return } fmt.Printf("Service \"%s\" installed.\n", displayName) case "remove": err = s.Remove() if err != nil { fmt.Printf("Failed to remove: %s\n", err) return } fmt.Printf("Service \"%s\" removed.\n", displayName) case "run": isService = false doWork() case "start": err = s.Start() if err != nil { fmt.Printf("Failed to start: %s\n", err) return } fmt.Printf("Service \"%s\" started.\n", displayName) case "stop": err = s.Stop() if err != nil { fmt.Printf("Failed to stop: %s\n", err) return } fmt.Printf("Service \"%s\" stopped.\n", displayName) } return } err = s.Run(func() error { // start go doWork() return nil }, func() error { // stop stopWork() return nil }) if err != nil { s.Error(err.Error()) } }
Il ne vous reste plus qu'à créer la fonction doWork (elle contiendra votre programme). Et on peut maintenant utiliser l'exécutable qui accepte un argument optionnel en ligne de commande :
Bien entendu, cela ne vous dispense pas d'éventuelles actions spécifiques à votre service. Par exemple, les opérations effectuées peuvent nécessiter l'emploi d'un autre compte. Veuillez dans ce cas configurer votre système de manière adéquate (par exemple sous Windows, il pourrait s'avérer nécessaire de lancer le service en tant qu'un autre utilisateur).
On peut utiliser la fonction Error pour reporter une erreur dans les fichiers de log du système :
logSrv.Error(logMessage, a...)
Ainsi que la fonction Error pour reporter une information dans les fichiers de log du système :
logSrv.Info(logMessage, a...)
La fonction main doit être la plus rapide possible. Surtout si le service tourne sous Windows, car le manager de service de ce système attend une réponse du service qu'il lance qui doit lui être retournée très rapidement (une sorte d'acquittement du fait que le service est lancé et prêt à être utilisé). Il est doit fortement déconseillé de faire des opérations longues telles que le chargement d'un fichier de configuration. Ce type d'opération devrait être réalisée dans la fonction doWork() dans notre exemple.
Avec la plupart des systèmes d'exploitation, le répertoire de travail de l'exécutable (implémentant le service) n'est pas le même que le répertoire d'installation. Il faut donc déterminer dans quel le dossier l'exécutable du service est installé. Puis utiliser ce chemin d'accès complet à chaque fois que l'on tente d'ouvrir un fichier. Vous pouvez lire cet article pour savoir comment faire. Ci-dessous, un exemple qui concerne l'ouverture du fichier de configuration de l'application :
XP, _ = osext.ExecutableFolder() CONFIGURATION_FILE = XP + "/conf/config.json"
Une traduction du blog officiel de golang expliquant le mécanisme de la réflexion en Go. Lire »
Traduction d'une partie des spécifications officielles du langage Go, cet article explique comment développer en Go. Lire »
Traduction d'un article du blog officiel expliquant comment échanger des données entre deux programmes golang grâce à un format natif Lire »
Préconisations officielles pour la gestion des erreurs dans un programme golang. Cet article complète les explications sur panic, defer et recover Lire »
Exemples d'utilisation du type chan et des go routines stateful et stateless Lire »
Soyez le premier à commenter cet article
Tous les commentaires sont soumis à modération. Les balises HTML sont pour la plupart autorisées. Les liens contextuels et intéressants sont en follow.