getinfo: CURLINFO_QUEUE_TIME_T

Returns the time, in microseconds, during which this transfer was held
in a waiting queue before it started "for real". A transfer might be put
in a queue if after getting started, it cannot create a new connection
etc due to set conditions and limits imposed by the application.

Ref: #12293
Closes #12368
This commit is contained in:
Daniel Stenberg 2023-12-27 09:28:48 +01:00
parent 2b221d4214
commit 68f96fc9bf
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
10 changed files with 109 additions and 11 deletions

View File

@ -95,6 +95,9 @@ See \fICURLINFO_PRETRANSFER_TIME(3)\fP
.IP CURLINFO_PRETRANSFER_TIME_T
Time from start until just before the transfer begins.
See \fICURLINFO_PRETRANSFER_TIME_T(3)\fP
.IP CURLINFO_QUEUE_TIME_T
Time during which this transfer was held in a waiting queue.
See \fICURLINFO_QUEUE_TIME_T(3\fP
.IP CURLINFO_STARTTRANSFER_TIME
Time from start until just when the first byte is received.
See \fICURLINFO_STARTTRANSFER_TIME(3)\fP
@ -259,14 +262,18 @@ An overview of the six time values available from \fIcurl_easy_getinfo(3)\fP
curl_easy_perform()
|
|--NAMELOOKUP
|--|--CONNECT
|--|--|--APPCONNECT
|--|--|--|--PRETRANSFER
|--|--|--|--|--STARTTRANSFER
|--|--|--|--|--|--TOTAL
|--|--|--|--|--|--REDIRECT
|--QUEUE_TIME
|--|--NAMELOOKUP
|--|--|--CONNECT
|--|--|--|--APPCONNECT
|--|--|--|--|--PRETRANSFER
|--|--|--|--|--|--STARTTRANSFER
|--|--|--|--|--|--|--TOTAL
|--|--|--|--|--|--|--REDIRECT
.fi
.IP "QUEUE_TIME"
\fICURLINFO_QUEUE_TIME_T(3\fP. The time during which the transfer was held in
a waiting queue before it could start for real. (Added in 8.6.0)
.IP NAMELOOKUP
\fICURLINFO_NAMELOOKUP_TIME(3)\fP and \fICURLINFO_NAMELOOKUP_TIME_T(3)\fP.
The time it took from the start until the name resolving was completed.

View File

@ -0,0 +1,74 @@
.\" **************************************************************************
.\" * _ _ ____ _
.\" * Project ___| | | | _ \| |
.\" * / __| | | | |_) | |
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
.\" * are also available at https://curl.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
.\" * furnished to do so, under the terms of the COPYING file.
.\" *
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
.\" * KIND, either express or implied.
.\" *
.\" * SPDX-License-Identifier: curl
.\" *
.\" **************************************************************************
.\"
.TH CURLINFO_QUEUE_TIME_T 3 "28 Apr 2018" libcurl libcurl
.SH NAME
CURLINFO_QUEUE_TIME_T \- time this transfer was queued
.SH SYNOPSIS
.nf
#include <curl/curl.h>
CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_QUEUE_TIME_T,
curl_off_t *timep);
.fi
.SH DESCRIPTION
Pass a pointer to a curl_off_t to receive the time, in microseconds, this
transfer was held in a waiting queue before it started "for real". A transfer
might be put in a queue if after getting started, it cannot create a new
connection etc due to set conditions and limits imposed by the application.
See also the TIMES overview in the \fIcurl_easy_getinfo(3)\fP man page.
.SH PROTOCOLS
All
.SH EXAMPLE
.nf
int main(void)
{
CURL *curl = curl_easy_init();
if(curl) {
CURLcode res;
curl_off_t queue;
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
res = curl_easy_perform(curl);
if(CURLE_OK == res) {
res = curl_easy_getinfo(curl, CURLINFO_QUEUE_TIME_T, &queue);
if(CURLE_OK == res) {
printf("Queued: %" CURL_FORMAT_CURL_OFF_T ".%06ld us", queue / 1000000,
(long)(queue % 1000000));
}
}
/* always cleanup */
curl_easy_cleanup(curl);
}
}
.fi
.SH AVAILABILITY
Added in 8.6.0
.SH RETURN VALUE
Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
.SH "SEE ALSO"
.BR curl_easy_getinfo (3),
.BR curl_easy_setopt (3),
.BR CURLINFO_STARTTRANSFER_TIME_T (3),
.BR CURLOPT_TIMEOUT (3)

View File

@ -65,6 +65,7 @@ man_MANS = \
CURLINFO_PROXY_ERROR.3 \
CURLINFO_PROXY_SSL_VERIFYRESULT.3 \
CURLINFO_PROXYAUTH_AVAIL.3 \
CURLINFO_QUEUE_TIME_T.3 \
CURLINFO_REDIRECT_COUNT.3 \
CURLINFO_REDIRECT_TIME.3 \
CURLINFO_REDIRECT_TIME_T.3 \

View File

@ -469,6 +469,7 @@ CURLINFO_PROXY_ERROR 7.73.0
CURLINFO_PROXY_SSL_VERIFYRESULT 7.52.0
CURLINFO_PROXYAUTH_AVAIL 7.10.8
CURLINFO_PTR 7.54.1
CURLINFO_QUEUE_TIME_T 8.6.0
CURLINFO_REDIRECT_COUNT 7.9.7
CURLINFO_REDIRECT_TIME 7.9.7
CURLINFO_REDIRECT_TIME_T 7.61.0

View File

@ -2936,7 +2936,8 @@ typedef enum {
CURLINFO_CAPATH = CURLINFO_STRING + 62,
CURLINFO_XFER_ID = CURLINFO_OFF_T + 63,
CURLINFO_CONN_ID = CURLINFO_OFF_T + 64,
CURLINFO_LASTONE = 64
CURLINFO_QUEUE_TIME_T = CURLINFO_OFF_T + 65,
CURLINFO_LASTONE = 65
} CURLINFO;
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as

View File

@ -409,6 +409,9 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
case CURLINFO_STARTTRANSFER_TIME_T:
*param_offt = data->progress.t_starttransfer;
break;
case CURLINFO_QUEUE_TIME_T:
*param_offt = data->progress.t_postqueue;
break;
case CURLINFO_REDIRECT_TIME_T:
*param_offt = data->progress.t_redirect;
break;
@ -420,7 +423,7 @@ static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
break;
case CURLINFO_CONN_ID:
*param_offt = data->conn?
data->conn->connection_id : data->state.recent_conn_id;
data->conn->connection_id : data->state.recent_conn_id;
break;
default:
return CURLE_UNKNOWN_OPTION;

View File

@ -1943,6 +1943,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
}
if(!result) {
*nowp = Curl_pgrsTime(data, TIMER_POSTQUEUE);
if(async)
/* We're now waiting for an asynchronous name lookup */
multistate(data, MSTATE_RESOLVING);

View File

@ -174,10 +174,18 @@ void Curl_pgrsTimeWas(struct Curl_easy *data, timerid timer,
data->progress.t_startop = timestamp;
break;
case TIMER_STARTSINGLE:
/* This is set at the start of each single fetch */
/* This is set at the start of each single transfer */
data->progress.t_startsingle = timestamp;
data->progress.is_t_startransfer_set = false;
break;
case TIMER_POSTQUEUE:
/* Set when the transfer starts (after potentially having been brought
back from the waiting queue). It needs to count from t_startop and not
t_startsingle since the latter is reset when a connection is brought
back from the pending queue. */
data->progress.t_postqueue =
Curl_timediff_us(timestamp, data->progress.t_startop);
break;
case TIMER_STARTACCEPT:
data->progress.t_acceptdata = timestamp;
break;

View File

@ -30,7 +30,8 @@
typedef enum {
TIMER_NONE,
TIMER_STARTOP,
TIMER_STARTSINGLE,
TIMER_STARTSINGLE, /* start of transfer, might get queued */
TIMER_POSTQUEUE, /* start, immediately after dequeue */
TIMER_NAMELOOKUP,
TIMER_CONNECT,
TIMER_APPCONNECT,

View File

@ -1189,6 +1189,7 @@ struct Progress {
curl_off_t dlspeed;
curl_off_t ulspeed;
timediff_t t_postqueue;
timediff_t t_nslookup;
timediff_t t_connect;
timediff_t t_appconnect;