> This should be `getReturn()`, no?
Yes it should, I'm very bad for sharing code that I've not actually run.
Sorry about that.

> In most stacks I've reviewed, you have middleware that
> contains a try/catch block; I have no idea if that would work here, or
> if that now becomes a requirement of the dispatcher. If the latter,
> that's a non-starter;
I'm pretty sure you wouldn't be able to catch any exceptions outside of the
yield, so the latter.

> I'll have to disagree with you on the "reduces the mental overhead a
> bit" statement! I had to go through the examples a few times to
> understand how middleware is processed (first outside-in, then
> inside-out); for those not familiar with generators, the example is
> extremely opaque and difficult to comprehend.
Again I was talking about the middleware not the dispatcher.

So yea, message received, non-starter.

On Wed, Aug 2, 2017 at 8:41 PM, Matthew Weier O'Phinney <
[email protected]> wrote:

> On Wed, Aug 2, 2017 at 10:52 AM, Simon Holloway <[email protected]>
> wrote:
> > I haven't been keeping up with this mailing list so maybe this has
> already
> > come up and I missed it.
> >
> > Did anyone consider using generators/yield instead of a delegate/frame?
> >
> > So instead of:
> >
> > interface MiddlewareInterface
> > {
> >     public function process(
> >         ServerRequestInterface $request,
> >         DelegateInterface $delegate
> >     ): ResponseInterface
> > }
> >
> >
> > class Timer implements MiddlewareInterface
> > {
> >     public function process(ServerRequestInterface $request,
> > DelegateInterface $delegate)
> >     {
> >         $startTime = microtime(true);
> >
> >         $response = $delegate->process($request);
> >         return $response->withHeader('X-Timer', sprintf('%2.3fms',
> > (microtime(true) - $startTime) * 1000));
> >
> >     }
> > }
> >
> >
> > We could do
> >
> > interface MiddlewareInterface
> > {
> >     public function process(ServerRequestInterface $request): Generator
> > }
>
> This is an interesting idea, but I feel it falls in the category of
> dictating architecture.
>
> One reason the DelegateInterface (soon to be "HandlerInterface") was
> chosen is to allow implementations to vary. While the majority of
> middleware frameworks have the delegate act as a stack, they don't
> _need_ to. The delegate passed could be simply something guaranteed to
> return a response, or it could use some sort of filtering algorithm to
> locate a suitable handler, etc.
>
> Additionally, as Woody noted, we lose out on the ability to guarantee
> that _something_ yields a response. By having the middleware be a
> generator, we have to somehow specify that eventually one of them
> needs to return a response; currently, PHP has no way of doing that.
> We also have no way of forcing the generator to yield a request to
> allow moving on to the next in the stack. If somebody yields a
> non-request, or returns a non-response, there's no guarantee operation
> will continue as expected.
>
> > class Timer implements MiddlewareInterface
> > {
> >     public function process(ServerRequestInterface $request)
> >     {
> >         $startTime = microtime(true);
> >
> >         $response = (yield $request);
> >         return $response->withHeader('X-Timer', sprintf('%2.3fms',
> > (microtime(true) - $startTime) * 1000));
> >
> >     }
> > }
> >
> >
> > Then to dispatch middleware, you would do the following:
> >
> > function dispatch(ServerRequestInterface $request, ResponseInterface
> > $response, array $middleware)
> > {
> >     $postProcessors = [];
> >     foreach ($middleware as $middleware) {
> >         $frame = $middleware($request);
> >         if ($frame->valid()) {
> >             $request = $frame->current();
> >             $postProcessors[] = $frame;
> >         } else {
> >             $response = $frame->getResponse();
>
> This should be `getReturn()`, no?
>
> >         }
> >     }
> >
> >     $postProcessors = array_reverse($postProcessors);
> >     foreach ($postProcessors as $frame) {
> >         $frame->send($response);
> >         $response = $frame->getReturn();
> >     }
> >     return $response;
> > }
>
> One thing I wonder about when looking at this is how error handling
> would occur. In most stacks I've reviewed, you have middleware that
> contains a try/catch block; I have no idea if that would work here, or
> if that now becomes a requirement of the dispatcher. If the latter,
> that's a non-starter; it's quite useful to be able to have different
> error handlers within the middleware stack in order to have granular
> error handling.
>
> > This would require >= PHP 7 due to needing Generator::getReturn() and you
> > loose some type hinting. Terminating middleware has to be a bit hacky, it
> > would have to use `yield from []` to create an empty generator, then
> return
> > a response. Also no catching thrown objects further down the app.
> >
> > On the positive side, I think it reduces the mental overhead a bit, makes
> > PSR-15 only 1 interface, keeps middleware out of stack traces, and
> promotes
> > a great feature of PHP.
>
> I'll have to disagree with you on the "reduces the mental overhead a
> bit" statement! I had to go through the examples a few times to
> understand how middleware is processed (first outside-in, then
> inside-out); for those not familiar with generators, the example is
> extremely opaque and difficult to comprehend.
>
> Also, as noted, it makes alternate delegation strategies impossible,
> as it essentially dictates one and only one way to implement a
> middleware stack. Having the freedom to implement the delegate any way
> you wish so long as it returns a response provides a lot of
> possibilities for developers, while retaining interoperability between
> implementations.
>
> --
> Matthew Weier O'Phinney
> [email protected]
> https://mwop.net/
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "PHP Framework Interoperability Group" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/
> topic/php-fig/lkpuaZPcBsY/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> [email protected].
> To post to this group, send email to [email protected].
> To view this discussion on the web visit https://groups.google.com/d/
> msgid/php-fig/CAJp_myVPNLwXexJs8U_NLdw9Kp1jo3%3Dcei5uh6cr-6ds%2BTwv-Q%
> 40mail.gmail.com.
> For more options, visit https://groups.google.com/d/optout.
>



-- 
Simon Holloway

-- 
You received this message because you are subscribed to the Google Groups "PHP 
Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/php-fig/CAErSA%3DYhvvBNZeQBU%2B_K2ZX2-oMu5u7u8F5cZqS4xc%2BCzg6P4g%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to