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

Base Dancer2::Core::Request on Plack::Request #911

Closed
wants to merge 8 commits into from

Conversation

xsawyerx
Copy link
Member

I couldn't see how to do the majority of this in more than one commit.

This commit bases D2::Core::Request on Plack::Request instead of delegating to an internal Plack::Request object.

This allows to utilize the existing implementation of many PSGI perspectives already available in Plack::Request while adding our own variations (such as using "is_behind_proxy") without having to keep another object around and delegating to it.

Here are also a few benchmarks showing about 13.57% increase in speed as a result of this change.

Before:

$ perl bench-request.pl
Ran 12 iterations (2 outliers).
Rounded run time per iteration: 9.741e+00 +/- 2.9e-02 (0.3%)

After:

$ perl bench-request.pl
Ran 11 iterations (1 outliers).
Rounded run time per iteration: 8.419e+00 +/- 3.3e-02 (0.4%)

@xsawyerx
Copy link
Member Author

@veryrusty, @shumphrey, @mickeyn, @yanick ?

@xsawyerx
Copy link
Member Author

Rebased. If no one says anything, I'm merging it tomorrow (US Eastern time).

@veryrusty
Copy link
Member

I've been slowly working through it!

First comment:

  • Does the request class really need the headers_to_array method? If so, can we avoid the duplication and include it as a role (may involve splitting the existing headers role..)

@xsawyerx
Copy link
Member Author

The idea is that headers_to_array is in a Moo Role but this PR removes the Moo dependency altogether.

@veryrusty
Copy link
Member

Use Role::Tiny directly.

@xsawyerx
Copy link
Member Author

We could. Then again, I think that method might just be redundant and unnecessary and we could remove it altogether. That's why for now I just copied it over.

@veryrusty
Copy link
Member

I think it is redundant. Converting headers to an array format like that only makes sense if you are generating a PSGI style response. Not something you'd do from request headers!

xsawyerx added a commit that referenced this pull request Jun 16, 2015
As indicated in the discussion on #911, the "headers_to_array"
method, which was originally available through
Dancer2::Core::Role::Headers, was copied over verbatim. In the
discussion, @veryrusty mentioned it is indeed redundant since it
is only used by a response. A request does not need to flatten its
headers.

Thus the method was removed.
@xsawyerx
Copy link
Member Author

Done. Rebased and pushed.

I couldn't see how to do the majority of this in more than one
commit.

** Why **

The purpose of this commit is to base D2::Core::Request on
Plack::Request instead of delegating to an internal Plack::Request
object.

This allows to utilize the existing implementation of many PSGI
prespectives already available in Plack::Request while adding our
own variations (such as using "is_behind_proxy") without having
to keep another object around and delegating to it.

** How **

Moo was stripped out. Instead we use "parent" to inherit. We
implement all the attributes in very stripped down simple
subroutines, and we copy the "headers_to_array" method from
Dancer2::Core::Role::Headers.

Because of this, "_preq" attribute (which held the Plack::Request
object we delegated to) can be removed, and any method which
called it was simply deleted since it's now available in our
class.

The "BUILDARGS" method allowed multiple ways to instantiate a new
request object, but those were experimental and not very useful,
and basing on "Plack::Request", they added complexity with no
gain. Subsequently, they were removed. Now, in order to create
a new instance, you simply call it with a key/value pair:

    Dancer2::Core::Request->new(
        env => {}, serializer => $s, is_behind_proxy => 0|1
    );

("serializer" and "is_behind_proxy" are not mandatory.)
The documentation reflects this new behavior as well.

All the attributes that are provided by Plack::Request have been
removed. All of the attributes that Plack::Request provides which
we didn't document were documented.

The "forwarded_protocol" method now takes into account all the
headers we know about (which we were checking in the "scheme"
method).

Every method that is incompatible is marked in the code.

The documentation had been almost completely rewritten. All of
the headers are now documented and accounted for, even those
provided by Plack::Request.

There are several additional tasks I've written down that have
to do with additional cleanups we can do.
The "headers" attribute from Plack::Request instantiates the
headers lazily, so there's no need to explicitly set it.

Additionally, it's immutable in Plack::Request, so we can't
actually override the value explicitly.
BUILD is recognized as an automatically-called method in Moo(se),
and keeping it under the same name will only add to the confusion.

Instead it's been renamed to "init".
The only thing this tested was whether the serializer was defined.
The only place we need it we might as well do a boolean check on
the serializer. No need. Additionally another call to serializer
was removed.
As indicated in the discussion on #911, the "headers_to_array"
method, which was originally available through
Dancer2::Core::Role::Headers, was copied over verbatim. In the
discussion, @veryrusty mentioned it is indeed redundant since it
is only used by a response. A request does not need to flatten its
headers.

Thus the method was removed.
xsawyerx added a commit that referenced this pull request Jun 18, 2015
As indicated in the discussion on #911, the "headers_to_array"
method, which was originally available through
Dancer2::Core::Role::Headers, was copied over verbatim. In the
discussion, @veryrusty mentioned it is indeed redundant since it
is only used by a response. A request does not need to flatten its
headers.

Thus the method was removed.
@xsawyerx xsawyerx closed this Jun 18, 2015
@xsawyerx xsawyerx deleted the feature/plack-request branch June 18, 2015 16:34
@xsawyerx
Copy link
Member Author

Merged!

@veryrusty
Copy link
Member

Yay! @xsawyerx++ Thanks!

xsawyerx added a commit that referenced this pull request Jul 8, 2015
    [ BUG FIXES ]
    * GH #915, #930: Check existence of optional extension headers when
      behind proxy. (Andy Beverley, Pedro Melo, Russell Jenkins)
    * GH #926, #940: Set session directory default to $apprdir/session.
      (Russell Jenkins)
    * GH #936, #939: Use the error_template configuration on a 404.
      (Russell Jenkins)
    * GH #844, #937: Non-hash serialized params do not cause a crash. (Sawyer X)
    * GH #943: Pass @_ to UNIVERSAL's VERSION so it validates version number.
      (Sawyer X)
    * GH #934: Cleanup internals in the old Dispatcher. (Russell Jenkins)

    [ DOCUMENTATION ]
    * Sanitize Changes
    * GH #938: Fix POD link to params keyword. (Ludovic Tolhurst-Cleaver)
    * GH #935: Provide more details and considerations when using
      behind_proxy. (Andy Beverley)

    [ ENHANCEMENT ]
    * GH #933: use note in tests to produce cleaner non-verbose output (Vernon)
    * Remove unnecessary dependencies: build chain should be smaller. (Sawyer X)
    * No need for Module::Build. (Sawyer X)
    * GH #911: Dancer2 request object is now a subclass of Plack::Request.
      It's also much faster now. (Sawyer X)
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.

None yet

2 participants