Skip to content

Asynchronously handle streamed responses #40

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 27, 2016
Merged

Conversation

andig
Copy link
Contributor

@andig andig commented May 30, 2016

This PR will send the StreamingResponse in 4k blocks instead of as chunk. This should improve performance and reduce memory usage.

Fixes #36

$stdOut .= $buffer;
// asynchronously get content
ob_start(function($buffer) use ($reactResponse) {
$reactResponse->write($buffer);
Copy link

@duxet duxet May 30, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea why, but this line makes my whole response body empty, with a not streamed response 😟

edit: it's working with if ($buffer), but output buffer is not added to final response 😶

Copy link
Contributor Author

@andig andig May 30, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea why, but this line makes my whole response body empty, with a not streamed response
but output buffer is not added to final response

Could you elaborate what that means? Which OS and which PHP version? I've had success testing this on Debian Jessie, php 5.6.

Does it mean that streamed response is working for you but not the regular response?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since all stuff here is asycnhronouse we can not do async stuff here. That will break since reactResponse->end() is called immediately some lines below. Also I don't get the point of using async method here because between this line and $reactResponse->end is nothing that can do something async.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marcj

Since all stuff here is asycnhronouse we can not do async stuff here. That will break since reactResponse->end() is called immediately some lines below. Also I don't get the point of using async method here because between this line and $reactResponse->end is nothing that can do something async.

I'm not sure what you mean. We get multiple ob callbacks for a single sendContent so that is async in a manner. $reactResponse->end is only called after sendContent finishes (and ob_end_flush is called)- so all buffers have been cleared.

What could I do to resolve the issue you see? I have tried this ;)

@andig
Copy link
Contributor Author

andig commented Jun 4, 2016

@duxet PR is updated. Non-streamed response is working now, too. It entirely escapes me why the content was not written before. It was definitely captured.

@marcj for sake of clarity I've split the streamed/ non-streamed path (though they could be combined). Difference to previous implementation is that STDOUT output for normal response is silently swallowed now- if you need it echoed please give me a hint.

One thing I've noticed during testing is that we're always sending chunked responses even in case of normal response where content length is known if upstream response doesn't contain content-length. As chunked is invented by react we might as well invent content-length ourselves to send simpler responses for basic clients? Please let me know if I should add that.

if ($this->bootstrap instanceof HooksInterface) {
$this->bootstrap->preHandle($this->application);
}

$syResponse = $this->application->handle($syRequest);

// should not receive output from application->handle()
ob_end_clean();
} catch (\Exception $exception) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a ob_end_clean call also in catch block I think. I guess its better to just let ob_start out of try and add
ob_end_clean after the whole try-catch.

Btw, tabs detected :P

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a ob_end_clean call also in catch block I think. I guess its better to just let ob_start out of try and add
ob_end_clean after the whole try-catch.

Btw, tabs detected :P

@marcj Will fix this. Could you also comment on the content-length?

@andig
Copy link
Contributor Author

andig commented Jun 7, 2016

PR updated and content-length for none-streamed response added.

@duxet please give it a try

@duxet
Copy link

duxet commented Jun 7, 2016

ok, i will try when i will be back home today

@andig
Copy link
Contributor Author

andig commented Jun 9, 2016

ping @duxet would be great if you could confirm that the non-streamed response is working, too. According to my tests the issue has been fixed.

@andig
Copy link
Contributor Author

andig commented Jun 20, 2016

ping @marcj @duxet is anything missing in order to get this in?

@andig
Copy link
Contributor Author

andig commented Jun 24, 2016

ping?

}
else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no line break please

@marcj marcj merged commit 4754a51 into php-pm:master Jun 27, 2016
@marcj
Copy link
Member

marcj commented Jun 27, 2016

Thanks, good work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants