Overview
El controlador Go utiliza el Paquete de contexto de la biblioteca estándar de Go que permite a las aplicaciones indicar tiempos de espera y cancelaciones para cualquier llamada a un método de bloqueo. Un método de bloqueo depende de un evento externo, como una entrada o salida de red, para continuar con su tarea.
Un ejemplo de un método de bloqueo es el InsertOne()
Método. Si desea realizar una operación de inserción en un Collection en 10 segundos, puede usar un contexto con un tiempo de espera. Si la operación no se completa dentro del tiempo de espera, el método devuelve un error.
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() client.Database("db").Collection("items").InsertOne(ctx, bson.D{{"x",1}})
Si el contexto pasado a una operación no tiene fecha límite, puede establecer una opción Timeout en su Client y la operación derivará la especificación de tiempo de espera de esta configuración. Para obtener más información sobre el uso de la configuración de tiempo de espera único, consulte
Limitar el tiempo de ejecución del servidor en la guía Opciones de conexión.
Caducidad
El controlador considera que un contexto ha expirado cuando una operación excede su tiempo de espera o se cancela. El controlador comprueba la expiración del contexto con el método Done().
Las siguientes secciones describen cuándo y cómo el controlador verifica la caducidad.
Selección de servidores
El controlador podría bloquear una llamada de método si no puede seleccionar un servidor para una operación.
En este escenario, el controlador realiza bucles hasta encontrar un servidor para utilizar en la operación. Después de cada iteración, el controlador devuelve un error de tiempo de espera de selección de servidor si el contexto expiró o si el proceso de selección tardó más que el ajuste serverSelectionTimeoutMS.
Para obtener más información sobre cómo el controlador selecciona un servidor, consulte la sección Leer inquietud en la guía Configurar operaciones CRUD.
Comprobación de la conexión
El controlador podría bloquear una llamada a un método si no hay conexiones disponibles para verificar.
Tras seleccionar un servidor, el controlador intenta extraer una conexión del pool de conexiones del servidor. Si el contexto expira al extraer una conexión, el método devuelve un error de tiempo de espera.
Establecimiento de conexión
El controlador podría bloquear una llamada a un método si debe crear una nueva conexión.
Cuando el controlador crea una nueva conexión para realizar una operación, el contexto establece un tiempo de espera para el proceso de establecimiento. El controlador establece el tiempo de espera como el vencimiento del contexto o el tiempo de espera de la conexión, el que sea más corto.
El siguiente ejemplo establece el tiempo de espera de la conexión en 1 segundos y la fecha límite del contexto 2 en segundos. Dado que el tiempo de espera de la conexión es menor, el proceso de establecimiento expira después de 1 segundos.
opts := options.Client() opts.SetConnectTimeout(1*time.Second) client, err := mongo.Connect(opts) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() client.Database("<db>").Collection("<collection>").InsertOne(ctx, bson.D{{"x",1}})
Lectura y escritura de sockets
Cuando el driver recupera una conexión para una operación, establece la fecha límite de lectura o escritura del socket a la fecha límite del Context o a la del tiempo de espera del socket, la que sea más corta.
Si cancela el contexto después de la ejecución del método Read() o Write() pero antes de su fecha límite, el comportamiento del controlador varía según la versión.
El controlador genera una goroutine independiente para detectar la cancelación de contexto cuando el método Read() o Write() está en curso. Si la goroutine detecta una cancelación, cierra la conexión. El método Read() o Write() pendiente devuelve un error que el controlador sobrescribe con el error context.Canceled.
Importante
En versiones anteriores a 1.5.0, el controlador no detecta la cancelación de contexto y espera a que regrese el método Read() o Write().