[CDRIVER-4545] Heartbeat poll cannot be canceled Created: 17/Dec/22  Updated: 10/Feb/23

Status: Backlog
Project: C Driver
Component/s: libmongoc
Affects Version/s: 1.23.1
Fix Version/s: None

Type: Improvement Priority: Unknown
Reporter: Valentin Garaschuk Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: techdebt
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Epic Link: Improve Developer Experience

 Description   

Summary

Destruction of "topology->server_monitors" can take up to 500ms, as the server is making a blocking heartbeat poll that cannot be canceled for 500ms (MONGOC_TOPOLOGY_MIN_HEARTBEAT_FREQUENCY_MS).

That makes mongoc quite slow to run in unit tests, as every case takes around 500ms.

Environment

Driver Versions 1.21.0-1.22.2. Probably older versions too.

System: Ubuntu 20.04 x64 and Windows 10 x64.

Compiler: GCC 9.3.0 and MSBuild v141.

Server version: 4.4.12.

How to Reproduce

  1. Initialize mongoc driver;
  2. Create mongoc client pool;
  3. Connect to MongoDB using the pool;
  4. Destroy the pool.

Actual result: mongoc_client_pool_destroy takes 500ms.

Additional Background

It looks like the heartbeat implemented in the way that client sends the heartbeat to the server and then relies on the server to send response in10 seconds, but not later than in 20 seconds. While waiting for the server's response the client polls the socket with 500ms intervals. Those intervals are blocking and cannot be cancelled. And there is no way to set heartbeat interval less than 500ms (Error parsing URI: 'Invalid "heartbeatfrequencyms" of 1: must be at least 500').

I feel like there should be an option to either cancel the poll, or make it much smaller if we want to keep it blocking.



 Comments   
Comment by Rishabh Bisht [ 10/Feb/23 ]

Thanks for the additional info, Valentin! This is helpful.

Comment by Valentin Garaschuk [ 10/Feb/23 ]

Hi Rishabh, unfortunately I was not able to use mongoc-interrupt-private.h. Once I try to include it, it also includes other headers, which trigger compilation error that says something like "this header can only be included via mongoc.h. However mongoc.h itself does not include mongoc-interrupt-private.h. Also the functions in mongoc-interrupt-private.h  are not exported, so I cannot import them from a binary. Also my project links mongocxx, it does not use mongoc directly, so it makes the matter even more complicated.

However, it looks like the code in  mongoc-interrupt-private.h does exactly what I need. So it would be nice if it was automatically triggered by mongoc when the poll needs to be interrupted.

Comment by Rishabh Bisht [ 10/Feb/23 ]

Hi valentin.garaschuk@gmail.com , just checking in - did the mongoc-interrupt-private.h suggestion fixed the issue for you?

Comment by Valentin Garaschuk [ 20/Dec/22 ]

Does this refer to tests in the C driver? Or external tests written that use the C driver?

I was referring to the external tests that use the driver.

there is an unused mongoc-interrupt-private.h that may solve this

I will check that.

Thank you.

Comment by Kevin Albertson [ 20/Dec/22 ]

Hello valentin.garaschuk@gmail.com, thank you for the report.

The 500ms delay on destroy is expected. Checks in between socket polls are 500ms.

IIRC this caveat was considered when adding polling, but not considered a blocker. mongoc_client_pool_t is expected to live for the duration of an application, so the delay on mongoc_client_pool_destroy is expected to occur only once at application shutdown.

That makes mongoc quite slow to run in unit tests, as every case takes around 500ms.

Does this refer to tests in the C driver? Or external tests written that use the C driver?

Opening this ticket for future consideration. Adding a test-only mechanism may speed up C driver tests. Also consider: there is an unused mongoc-interrupt-private.h that may solve this. It may provide a way to interrupt the call to mongoc_stream_poll.

Generated at Wed Feb 07 21:21:14 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.