Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

MultiCurl: Callbacks aren't called and new connections aren't started until a batch completes #903

Open
@ricnava00

Description

@ricnava00

When starting a MultiCurl batch with >1 parallel connections, in the default case no handling actions are taken (executing callbacks or starting new connections) until a whole parallel batch is concluded
This is because of the loop at

do {
$status =curl_multi_exec($this->multiCurl,$active);
}while ($status ===CURLM_CALL_MULTI_PERFORM);
that doesn't finish until all the requests in the batch are completed

This doesn't happen when calling setRequestTimeAccuracy() before starting the MultiCurl, since the other branch is executed.

Since i couldn't trigger the curl_multi_exec error described in the previous lines, I don't know what can be changed and what cannot, so I'm writing this issue instead.

Here is a simple test to replicate the issue:

useCurl\MultiCurl;constTEST_URL="https://ash-speed.hetzner.com/100MB.bin";$multi_curl =newMultiCurl();//$multi_curl->setRequestTimeAccuracy(); //Uncomment for expected output$start_time=microtime(true);foreach(range(1,12)as$i){$ch=$multi_curl->addGet(TEST_URL);$ch->setOpt(CURLOPT_MAX_RECV_SPEED_LARGE,100*$i*1024);$ch->setRange("0-".(500*1024));$ch->beforeSend(function()use ($i,$start_time){echo"Start$i at".round(microtime(true)-$start_time,2)."\n";});$ch->complete(function()use ($i,$start_time){echo"End$i at".round(microtime(true)-$start_time,2)."\n";});}$multi_curl->setConcurrency(3);$multi_curl->start();

This downloads the first 500KB of a test file multiple times, at speeds increasing by 100KB/s for every connection, and with 3 parallel connections
This means that connection 1 should take 500/100 = 5 seconds, connection 2 should take 500/200 = 2.5 seconds, and so on

Without calling setRequestTimeAccuracy, this is the output I get

Start 1 at 0Start 2 at 0Start 3 at 0End 3 at 4.96End 2 at 4.96End 1 at 4.97Start 4 at 4.97Start 5 at 4.97Start 6 at 4.97End 6 at 6.21End 5 at 6.21End 4 at 6.22Start 7 at 6.22Start 8 at 6.22Start 9 at 6.22End 9 at 6.93End 8 at 6.93End 7 at 6.93Start 10 at 6.93Start 11 at 6.93Start 12 at 6.93End 12 at 7.43End 11 at 7.44End 10 at 7.44

As you can see, while connection 3 is supposed to be 3 times faster, it will wait until connection 1 and 2 are finished, and then connections 4, 5 and 6 will be started

When calling setRequestTimeAccuracy, the output becomes

Start 1 at 0Start 2 at 0Start 3 at 0End 3 at 1.66Start 4 at 1.66End 2 at 2.48Start 5 at 2.48End 4 at 2.9Start 6 at 2.9End 5 at 3.48Start 7 at 3.48End 6 at 3.73Start 8 at 3.73End 7 at 4.19Start 9 at 4.19End 8 at 4.35Start 10 at 4.35End 9 at 4.74Start 11 at 4.74End 10 at 4.85Start 12 at 4.85End 1 at 4.96End 11 at 5.19End 12 at 5.26

Now, the callback for connection 3 is called as expected, and connection 4 is started right after
The total runtime is also lower, since new connections are started as soon as possible

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp