Clients
Client object is a client that can connect to the database servers over TCP, UDP and Unix Domain Socket. When GatewayD starts, a set of client objects are created that immediately connect to the users’ database and are put into the pool. Each client works independently, and a group of connections are connected to the same database server. The connection are gradually recycled.
Pools and proxies
The clients work directly with the pool and the proxy objects. When a new client connection is established, it is put into the pool it belong to. In turn, the pool itself belongs to a proxy object.
Receive chunk size
Usually the incoming queries are small and can easily be sent to the database server for processing. However, the result of the query might be enormous. For the client to receive all the data at once, so it can send it to the database clients. For this, the client needs to read the kernel’s buffer multiple times and concatenate the bytes to reconstruct the entire message. Internally, the client has a growing buffer, but for reading individual chunks, it needs a smaller buffer. The current default size of the chunk size is 8192
bytes.
The chunk size is adjustable, however, there is a trade-off. The smaller the number, the more it might take to read the entire message into the internal buffer. You can try to adjust the chunk size based on the response size from your database server.
The response size can be observed by setting the (log) level of the logger to
debug
and watching messages with the following format. Thelength
key shows the response size in bytes.2023-04-15T14:08:28+02:00 DBG Received data from database function=proxy.passthrough length=468 local=... remote=...
You can also use tools such as fluentbit to stream and aggregate the logs to find the patterns.
Send and receive deadlines
You have the option to set deadlines on send and receive calls to the database server. The client, in turn, sets the deadlines on the underlying connection object.
Setting send and receive deadlines are tricky, as the database server might kill the connection abruptly if it ceases to receive the data in whole. This also makes the connection unstable.
Receive timeout
Since setting receive deadline kills the connection, the receiveTimeout
property is introduced to stop the receive function from blocking the connection and waiting forever. The current value is zero, which means that it behaves like before, but one can set it to a duration string value.
Dial timeout
The dial timeout is the amount of time the client should wait before giving up on dialing the database. The default value is 60s
. Setting it to 0s
disables the dial timeout.
Retries and backoff
The first attempt to connect to the database server is made when the client is created, which happens instantly when GatewayD starts. However, if the first attempt fails, the client will retry the connection. The default number of retries is 3
, which means that the client will retry the connection three times before giving up. Setting it to 0
disables the retry mechanism. The client can also back off before retrying the connection. The backoff duration is set to 1s
by default and 0s
disables the backoff mechanism. The backoff multiplier is set to 2
by default and 0
disables the backoff. The backoff multiplier is applied to the backoff duration. The backoff duration is capped at 60s
by default and the max retry is capped at 10
by default. Setting disableBackoffCaps
to true
disables the backoff and retry caps.
The first attempt to connect to the database server is counted as a retry, hence the three retries are actually four attempts (one instant attempt and three retry attempts), and the backoff duration is applied to the second attempt and so on.
The backoff duration is calculated by multiplying the backoff duration by the backoff multiplier raised to the power of the number of retries. For example, if the backoff duration is 1 second and the backoff multiplier is 2, the backoff duration will be 1 second, 2 seconds, 4 seconds, 8 seconds, etc. The backoff duration is capped at 1 minute and the backoff multiplier is capped at 10, so the backoff duration will be 1 minute after 6 retries. The backoff multiplier is capped at 10 to prevent the backoff duration from growing too quickly, unless the backoff caps are disabled. The following is the formula for calculating the backoff duration:
backoff duration = backoff * (backoff multiplier ^ current retry number)
Considering the default values, the backoff duration will be calculated as follows:
1 * 2 ^ 1 = 2 seconds
1 * 2 ^ 2 = 4 seconds
1 * 2 ^ 3 = 8 seconds
If the retries are set to 11
, the backoff duration from the fourth attempt will be calculated as follows, which is capped at 1 minute and 10 retries are made:
1 * 2 ^ 4 = 16 seconds
1 * 2 ^ 5 = 32 seconds
1 * 2 ^ 6 = 1 minute
1 * 2 ^ 7 = 1 minute (capped)
1 * 2 ^ 8 = 1 minute (capped)
1 * 2 ^ 9 = 1 minute (capped)
1 * 2 ^ 10 = 1 minute (capped)
And if the backoff caps are disabled, the uncapped backoff duration for the fourth attempt will be calculated as follows:
1 * 2 ^ 4 = 16 seconds
1 * 2 ^ 5 = 32 seconds
1 * 2 ^ 6 = 1 minute 4 seconds (uncapped)
1 * 2 ^ 7 = 2 minutes 8 seconds (uncapped)
1 * 2 ^ 8 = 4 minutes 16 seconds (uncapped)
1 * 2 ^ 9 = 8 minutes 32 seconds (uncapped)
1 * 2 ^ 10 = 17 minutes 4 seconds (uncapped)
1 * 2 ^ 11 = 34 minutes 8 seconds (uncapped)