The below code snippet (reduced for brevity) from MongoDB's Go quickstart blog post creates context.WithTimeout
at the time of connecting with the database and reuses the same for the deferred Disconnect
function, which I think is buggy.
func main() {
client, _ := mongo.NewClient(options.Client().ApplyURI("<ATLAS_URI_HERE>"))
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
_ = client.Connect(ctx)
defer client.Disconnect(ctx)
}
My train of thought-
context.WithTimeout
sets a deadline in UNIX time at the point it is created.
So, passing it to Connect
makes sense as we want to cancel the process of establishing the connection if it exceeds the time limit (ie, the derived UNIX time).
Now, passing the same ctx
to the deferred Disconnect
, which will most probably be called late in the future, will result in the ctx
's time being in the past. Meaning, it is already expired when the function starts executing. This is not what is expected and breaks the logic as- quoting the doc for Disconnect
-
If the context expires via cancellation, deadline, or timeout before the in use connections have returned, the in use connections will be closed, resulting in the failure of any in flight read or write operations.
Please tell me if and how I am wrong and/or missing something.
Your understanding is correct.
In the example it is sufficient because the example just connects to the database, performs some example operation (e.g. lists databases), then main()
ends, so running the deferred disconnect with the same context will cause no trouble (the example will/should run well under 10 seconds).
In "real-world" applications this won't be the case of course. So you will likely not use the same context for connecting and disconnecting (unless that context has no timeout).