Home >Backend Development >Golang >Golang cli application - how to use context correctly?
Golang cli application - how to use context correctly? PHP editor Yuzai will introduce you how to use context correctly in Golang's cli application. When developing cli applications, context is very important, it can help us manage the state of the application, pass parameters and errors, etc. This article will explain the concept of context in detail and give some practical application examples to help you better understand and apply context. Whether you are a beginner or an experienced developer, this article will help you. Let’s dive into the context in a Golang cli application!
I am new to golang and a little confused about context and how to use context in golang application. Specifically, I'm developing a cli application that only needs access to mongo, for example.
Like - I just create a single shared ctx context variable and then use it for any action that requires context, is this correct?
Will any operation that requires context restart the 5-second timer? Or is this a shared timer?
package main import ( "context" "log" "os" "time" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/readpref" ) func main() { log.SetOutput(os.Stdout) // Create a context with a timeout of 5 seconds //This defines a timeout context that will be canceled after 5 seconds. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) // always defer in case func returns early defer cancel() //Creates a new ClientOptions instance. clientOptions := options.Client() clientOptions = clientOptions.ApplyURI("mongodb+srv://127.0.0.1?retryWrites=true&w=majority") //Connect to mongo client, err := mongo.Connect(ctx, clientOptions) defer client.Disconnect(ctx) if err != nil { log.Fatal(err) } //Test connection to the database log.Println("I: test mongo connection using ping") err = client.Ping(ctx, readpref.Primary()) if err != nil { log.Fatal(err) } log.Println("I: Fin") }
If you think about it, context.context
can be shared "horizontally" (meaning between operations that do not belong to the same call stack) Yes meaningless. golang context
provides the context in which the operation is to be performed (including any nested operations below it in the call stack) - e.g. "within x seconds", to prevent hangs due to communication delays etc. So if you make 10 requests in parallel, you should give each request its own context - you probably don't want the tenth request to fail because the first failed. If you're just using context.background()
or context.todo()
without further decoration, you probably don't need to add context# when you first create it ## Stored in a variable - you can create it at creation time by passing it to the first function in the call stack, properly constructed code will pass it down the stack as needed, applying the necessary decorations along the way:
func Execute() { DoThing(context.Background()) // Other stuff } func DoThing(pctx context.Context) { ctx, cancel := context.WithTimeout(pctx, 10 * time.Second) // Timeout after 10 seconds defer cancel() DoThingThatMayTakeAWhile(ctx) select { // You may want other stuff here case <-ctx.Done(): // Context timed out, maybe log an error? } } func DoThingThatMayTakeAWhile(pctx context.Context) { DoThingNeedingInfoInContext(context.WithValue(pctx, "thisisakey", "value")) } func DoThingNeedingInfoInContext(ctx context.Context) { val := ctx.Value("thisisakey") // Do something with val, check that it isn't nil, etc. }If I were to call
dothingthatmaytakeawhile() multiple times, I'd like to have a separate subcontext for each call - I
don't want to share the ctx with each call .
p> Therefore, in
your code, each call to mongo.connect() should receive a newly created
context.context instance.
The above is the detailed content of Golang cli application - how to use context correctly?. For more information, please follow other related articles on the PHP Chinese website!