Skip to content
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

!!! TASK: Remove dispatched state from ActionRequest #3301

Draft
wants to merge 4 commits into
base: temporary-mvc-refactoring-target-branch
Choose a base branch
from

Conversation

kitsunet
Copy link
Member

@kitsunet kitsunet commented Feb 2, 2024

I will dig a bit into history as I guess something (that obviously no one cares about) was lost in the PSR HTTP refactoring. I think (as we can see in the dispatch loop) there was a possibility before for a controller to gain control but decide it does not finally dispatch the request and thus the dispatch loop would continue and try to find another controller to take care, so it was the controllers responsibility to set this, but I am not sure what conditions it previously attached to it being dispatched.

Upgrade instructions

Review instructions

Checklist

  • Code follows the PSR-2 coding style
  • Tests have been created, run and adjusted as needed
  • The PR is created against the lowest maintained branch
  • Reviewer - PR Title is brief but complete and starts with FEATURE|TASK|BUGFIX
  • Reviewer - The first section explains the change briefly for change-logs
  • Reviewer - Breaking Changes are marked with !!! and have upgrade-instructions

Comment on lines 139 to 138
if ($request->isMainRequest()) {
return $response;
}
$request = $request->getParentRequest();
Copy link
Member

Choose a reason for hiding this comment

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

as discussed we concluded that this logic might be faulty and actually do harm without the isDispatched in place.

background:

the dispatcher is either used for main request, in which case this logic is not needed,
or for subrequest like in a fusion plugin

scenario:

a subrequest, while being handled, throws a StopActionException.
which is catched here. We check if its a main request and get the main request which is now to be handled in the loop, like a forward.

Thesis:

Now it will actually render the outer response inside the plugin
But previously because the main request was dispatched === true, it would not be handled.

So in theory this is dead code, and now must be removed.

Copy link
Member

Choose a reason for hiding this comment

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

Yes the thesis seems to be correct. Using throwStatus in a plugin will result in the main request rendering being started again an again until the memory is exhausted.

Removing this code will actually make the tests dispatchIgnoresStopExceptionsForFirstLevelActionRequests and dispatchCatchesStopExceptionOfActionRequestsAndRollsBackToTheParentRequest fail, so i wanted to research about the original intentions.
It seems that with the introduction ff05084#diff-450585af3bb27be2be268192637242195c5d6308512fd53dac9fa248ff319686 of sub request, this logic was introduced. (perviously all first level StopActionException where silently swallowed)

} catch (\F3\FLOW3\MVC\Exception\StopActionException $stopActionException) {
    if ($request instanceof \F3\FLOW3\MVC\Web\SubRequest && $request->isDispatched()) {
        throw $stopActionException;
    }
}

@mhsdesign
Copy link
Member

We further discussed that the ActionReponse doesnt need to be mutable anymore, and all its setters should be either deprecated or made internal.

One must use the ForwardException with attached $nextRequest instead to keep the dispatch loop going.

@mhsdesign mhsdesign force-pushed the temporary-mvc-refactoring-target-branch branch 2 times, most recently from 080c854 to f37ce2c Compare March 3, 2024 09:15
@mhsdesign mhsdesign force-pushed the remove-dispatched-action-request branch 2 times, most recently from e1491b0 to 2414a7b Compare March 3, 2024 09:48
mhsdesign and others added 3 commits March 3, 2024 10:51
TLTR:

Since the separation of http and cli requests the interface is completely unused. And strict types against its only implementation, the ActionRequest make it impossible to implement a custom request.

--------

_Initially_ the interface was introduced with 2a26925 at beginning of time. At that time this was done probably to be able to type against the interface instead of the common `Request` class, that the Cli and Web Request both extended.

With the removal of many methods in its interface 8c40ff2 and with the full separation of action and cli requests #1552 the interface became useless.

The dispatcher and controller interface are both typed against the `ActionRequest` and so it's impossible to implement a custom request.
@mhsdesign mhsdesign force-pushed the remove-dispatched-action-request branch from 2414a7b to faef9bc Compare March 3, 2024 09:51
…patcher

As discussed we concluded that this logic might be faulty and actually do harm without the `isDispatched` in place:

Background:

the dispatcher is either used for main request, in which case this logic is not needed, or for subrequest like in a fusion plugin

Scenario:

A subrequest, while being handled, throws a `StopActionException`.
which is caught here. We check if it's a main request and get the main request which is now to be handled in the loop, like a forward.

Thesis:

Now it will actually render the outer response inside the plugin
But previously because the main request was dispatched === true, it would not be handled.

Example:

Using `throwStatus` in a plugin will result in the main request rendering being started again and again until the memory is exhausted.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants