当前位置:网站首页>Explication contextuelle du langage Go

Explication contextuelle du langage Go

2022-07-07 05:42:00 Poussière coulée

GO Dans la langue Context Détails de l'emballage

Author mogd 2022-06-28
Update mogd 2022-07-04
Adage Rreality is merely an illusion, albeit a very persistent one.

Préface

Je me demande s'il y a des petits amis comme moi,Apprendre go Quand les bases de la langue,Besoin rencontré context Information,C'est direct context.TODO(),Pas d'étude approfondie Context

Laissez l'auteur en savoir plus Context Le sac est en train d'écrire un K8S CMDB Sur la plateforme, Penser à la nécessité d'initialiser les données (Est de créer admin Utilisateurs, Et les utilisateurs de tests , Et la répartition correspondante Casbin Autorité)

Parce que user Référence du module gin-vue-admin,Et dans GVA La section initialisation des données est également disponible dans , Cette partie du Code utilise Context

Lisez attentivement ,C'est vrai Context Le sac a une meilleure compréhension

L'amertume enfouie ne connaît souvent que sa forme et ne sait pas ce qu'elle veut dire , Ce n'est qu'en faisant des projets que nous pourrons vraiment maîtriser une langue

L'auteur lui - même a écrit K8S CMDB Interface arrière de la plate - forme ,gin-kubernetes
Celui - ci vient de commencer à écrire ,C'est très simple.,Si vous êtes intéressé, vous pouvez voir; J'espère que les grands feront des suggestions.
user Référence du module gin-vue-admin

Un.、Context Introduction

1.1 Context Qu'est - ce que c'est??

Context In Go1.7 Ajouter à Go Dans la Bibliothèque des normes linguistiques,- Oui. Goroutine Le contexte de,Contient Goroutine État de fonctionnement、Environnement、Informations sur le site, etc.

In Go servers, each incoming request is handled in its own goroutine. Request handlers often start additional goroutines to access backends such as databases and RPC services. The set of goroutines working on a request typically needs access to request-specific values such as the identity of the end user, authorization tokens, and the request’s deadline. When a request is canceled or times out, all the goroutines working on that request should exit quickly so the system can reclaim any resources they are using.
At Google, we developed a context package that makes it easy to pass request-scoped values, cancellation signals, and deadlines across API boundaries to all the goroutines involved in handling a request

Go En service, Chaque demande sera indépendante goroutine Traitement,Chaque goroutine En général, de nouveaux goroutine Effectuer des travaux supplémentaires , Comme faire une base de données ou RPC Accès aux services. Comme dans la demande goroutine Besoin de partager l'accès aux données demandées ,Par exemple,,Authentification de l'utilisateur,Autorisation token, Et la date limite de demande . En cas de demande d'annulation ou de délai d'attente , Tous les goroutine Devrait sortir immédiatement ,Récupération des ressources
In Google,Nous avons développé un context Le sac de,Par là., Nous pouvons très commodément demander goroutine Transfert des données demandées entre 、 Signal d'annulation et message de temporisation

D'après la présentation officielle,Context Emballé pour goroutine Transmettre des messages entre.C'est avec nous goroutine Utilisé entre channel C'est très similaire.,Mais c'est différent.Parce que dans un autre goroutine Il ne passe que done channel Trop peu d'informations

Et avec Context Introduction du paquet, De nombreuses interfaces de la Bibliothèque standard ont été ajoutées Context Paramètres,Context Est devenu presque la pratique standard pour le contrôle de la concurrence et le contrôle des temps d'arrêt

Context Utiliser le scénario

  • Transmission d'informations contextuelles (request-scoped),Comme le traitement http Demande、 Transmission de l'information sur la chaîne de traitement des demandes
  • Controller goroutine Fonctionnement
  • Appel de méthode pour le contrôle des temps d'arrêt
  • Appel de méthode annulable

1.2 Context Interface

context Au cœur de Context Type

// A Context carries a deadline, cancellation signal, and request-scoped values
// across API boundaries. Its methods are safe for simultaneous use by multiple
// goroutines.
type Context interface {
    
    // Done returns a channel that is closed when this Context is canceled
    // or times out.
    Done() <-chan struct{
    }

    // Err indicates why this context was canceled, after the Done channel
    // is closed.
    Err() error

    // Deadline returns the time when this Context will be canceled, if any.
    Deadline() (deadline time.Time, ok bool)

    // Value returns the value associated with key or nil if none.
    Value(key interface{
    }) interface{
    }
}
  • Done La méthode renvoie un channel, Il peut être utilisé pour recevoir context Signal d'annulation de.Quand channel Fermer,Écouter Done La fonction du signal annule immédiatement le travail en cours et renvoie
  • Err La méthode renvoie un error Variables, On peut en déduire que context Pourquoi il a été annulé .pipeline and cancelation - Oui. Done channel Une présentation détaillée a été faite.
  • Deadline La méthode permet à la fonction de décider si le travail doit être démarré , Si le temps restant est trop court , Alors ça ne vaut pas la peine de commencer le travail .Dans le Code,On peut passer par deadline Pour IO Délai de réglage de l'opération
  • Value Comment faire context In goroutine Partage des données dans le cadre de la demande entre , Ces données doivent être co - traitées et sécurisées simultanément

Si Done Pas par close,Err Retour de la méthode nil;Si Done Par close,Err La méthode renvoie Done Par close Raisons

2.、Context Utilisation de

In Google, Pour une fonction qui reçoit ou envoie une classe de requête , Nous exigeons que Context Passer comme premier paramètre .Voilà., Même si différentes équipes Go Le Code peut aussi bien fonctionner .Context Très pratique goroutine Timeout and uncontrol for , Et assurer la transmission sécurisée des données vitales , Comme un certificat de sécurité

context Le package offre principalement deux façons de créer Context

  • context.Background()
  • context.TODO()

Les deux fonctions sont alias l'une de l'autre ,Pas de différence.,Définitions officielles:

  • context.Background Est la valeur par défaut pour le contexte, Tous les autres contextes devraient en dériver (Derived) Sors de là.
  • context.TODO() Ne devrait être utilisé que lorsque le contexte à utiliser n'est pas certain

Créé de ces deux façons context,Pas de fonction, Sa mise en œuvre repose sur context Fourni par le paquet with Série dérivée

func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
func WithValue(parent Context, key, val interface{
    }) Context

Un projet pour Context Utilisation de, Avec ces quatre fonctions dérivées , Pour former un Context Nombre. Chaque noeud de l'arbre peut avoir n'importe quel nombre d'enfants ,Il peut y avoir plus d'un niveau de noeud, Chaque noeud enfant dépend du noeud parent

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-SslcluBn-1656939722939)(./images/context-derive.png)]

2.1 WithValue Données de transport、Value Obtenir des données

Voici le projet Open Source GVA Par exemple, le Code de la section initialisation des données dans , Certains jugements et codes de données ont été supprimés ,C'est réservé. context Section

// InitDB Créer une base de données et initialiser Entrée principale
func (initDBService *InitDBService) InitDB(conf request.InitDB) (err error) {
    
	ctx := context.TODO()

	var initHandler TypedDBInitHandler
	
	initHandler = NewMysqlInitHandler()
	ctx = context.WithValue(ctx, "dbtype", "mysql")
	
	ctx, _ = initHandler.EnsureDB(ctx, &conf)
	
	db := ctx.Value("db").(*gorm.DB)
	global.GVA_DB = db

	if err = initHandler.WriteConfig(ctx); err != nil {
    
		return err
	}
	if err = initHandler.InitTables(ctx, initializers); err != nil {
    
		return err
	}
	if err = initHandler.InitData(ctx, initializers); err != nil {
    
		return err
	}

	return nil
}

// EnsureDB Créer une base de données et initialiser mysql
func (h MysqlInitHandler) EnsureDB(ctx context.Context, conf *request.InitDB) (next context.Context, err error) {
    
	if s, ok := ctx.Value("dbtype").(string); !ok || s != "mysql" {
    
		return ctx, ErrDBTypeMismatch
	}
	c := conf.ToMysqlConfig()
	next = context.WithValue(ctx, "config", c)
	next = context.WithValue(next, "db", db)
}


// WriteConfig mysql Mise à jour de la configuration 
func (h MysqlInitHandler) WriteConfig(ctx context.Context) error {
    
	c, _ := ctx.Value("config").(config.Mysql)

	global.GVA_CONFIG.Mysql = c
	return global.GVA_VP.WriteConfig()
}

Basé sur context.TODO() Créé un ctx,Adoption context.WithValue Oui. dbtype, config Et db Écrire context,Et à travers context Transmission des arbres , Tout dérivé de context Ont accès à ces trois informations

Dans le Code context Processus:

  1. InitDB Écrire dbtype,EnsureDB Adoption Value Accès dbtype Déterminer si le type de base de données est correct
  2. EnsureDB Écrire config Et db Information
  3. WriteConfig Accès config Retour au profil de contenu
  4. InitDB Accès db Information,Assigner une valeur à une variable globale,Je l'ai. gorm.DB Client

Pour withValue Il y a quatre précautions pour l'utilisation de :

  • Non recommandé context Paramètres clés de transfert de valeur,Les paramètres clés doivent être affichés avec une déclaration,Il ne faut pas traiter implicitement
  • Transport value C'est aussi keyvalue Forme,Pour éviter context Parce que plusieurs paquets sont utilisés en même temps context Et apporter des conflits,key Le type intégré est recommandé
  • Obtenir la paire de clés , Doit commencer par le courant context Recherche dans,Je n'ai pas trouvé ce qui allait arriver du père context Trouve la valeur de cette clé jusqu'à ce qu'elle soit dans un parent context Retour au milieu nil Ou trouver la valeur correspondante
  • context Parmi les données transmises keyvalue Tous. interface Type,Le temps de compilation de ce type ne peut pas déterminer le type,Donc ce n'est pas très sûr,N'oubliez donc pas de garantir la robustesse du programme lors de l'affirmation de type

2.2 WithCancel Annuler le contrôle

Dans le développement quotidien des affaires, il y a souvent plus d'une demande complexe goroutine Pour faire quelque chose,Cela nous amène à ouvrir plus d'une demande goroutine Je ne peux vraiment pas les contrôler,C'est là que nous pouvons utiliser withCancel Pour dériver un context Passer à un autre goroutine Moyenne, Quand on veut que ça goroutine Arrête de courir,Pour appeler cancel Pour annuler

L'exemple ci - dessus est le suivant InitTables Et InitData Section

func (h MysqlInitHandler) InitTables(ctx context.Context, inits initSlice) error {
    
	return createTables(ctx, inits)
}
// createTables Créer une table(Par défaut dbInitHandler.initTables Comportement)
func createTables(ctx context.Context, inits initSlice) error {
    
	next, cancel := context.WithCancel(ctx)
	defer func(c func()) {
     c() }(cancel)
    return nil
}

func (h MysqlInitHandler) InitData(ctx context.Context, inits initSlice) error {
    
	next, cancel := context.WithCancel(ctx)
	defer func(c func()) {
     c() }(cancel)
    return nil
}

Mais GVA Cette partie de l'exemple n'est pas beaucoup goroutine De, Plus de présentation context Transmission d'informations contextuelles

Donc le contrôle est annulé , Voir l'exemple suivant pour plus de détails context Contrôle goroutine

func main()  {
    
    ctx,cancel := context.WithCancel(context.Background())
    go CancelText(ctx)
    time.Sleep(10*time.Second)
    cancel()
    time.Sleep(1*time.Second)
}

func CancelText(ctx context.Context)  {
    
    for range time.Tick(time.Second){
    
        select {
    
        case <- ctx.Done():
            fmt.Println("stop time")
            return
        default:
            fmt.Println("start time")
        }
    }
}

Utiliser WithCancel Créer un Background De ctx; main Appel principal de la fonction CancelText Sous - processus, Sous - programme imprimé en continu start time,Jusqu'à ctx.Done() Fermeture réussie

Le programme principal est 10s Mise en œuvre postérieure cancel,CancelText Sortie du sous - programme après la détection du signal d'annulation

RÉFÉRENCES

[1] Go Concurrency Patterns: Context
[2] Xiaobai peut comprendre.contextDétails de l'emballage:De l'initiation à la maîtrise

原网站

版权声明
本文为[Poussière coulée]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207062355469179.html