Message from discussion
Lazy-loaded and memoized processing
Received: by 10.151.38.11 with SMTP id q11mr1776743ybj.12.1230163047844;
Wed, 24 Dec 2008 15:57:27 -0800 (PST)
Return-Path: <chiol...@gmail.com>
Received: from qw-out-2122.google.com (qw-out-2122.google.com [74.125.92.25])
by mx.google.com with ESMTP id 7si3103894yxg.5.2008.12.24.15.57.26;
Wed, 24 Dec 2008 15:57:26 -0800 (PST)
Received-SPF: pass (google.com: domain of chiol...@gmail.com designates 74.125.92.25 as permitted sender) client-ip=74.125.92.25;
Authentication-Results: mx.google.com; spf=pass (google.com: domain of chiol...@gmail.com designates 74.125.92.25 as permitted sender) smtp.mail=chiol...@gmail.com; dkim=pass (test mode) header...@gmail.com
Received: by qw-out-2122.google.com with SMTP id 8so4129023qwh.63
for <rack-devel@googlegroups.com>; Wed, 24 Dec 2008 15:57:26 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=gamma;
h=domainkey-signature:received:received:message-id:date:from:to
:subject:in-reply-to:mime-version:content-type:references;
bh=qaahYof5pea34LSRNfkpF6waqd2uPyzWil7YWMvwNTA=;
b=R4Q946tadUroNssMfmGX4IHMnBFolciY4tK5qLQAPLNDxWLVQuwC26HKO8zaOWijcq
ENkpTf0R/iy+ncLge7hqLqHBI2GoM4ZgMP2KXW1izxy9jE2Bg/DDI+DslrlnDLE+DMMM
KQGKAQxK5QuyymT1Dv1jyCKy47TFn404NWi2Q=
DomainKey-Signature: a=rsa-sha1; c=nofws;
d=gmail.com; s=gamma;
h=message-id:date:from:to:subject:in-reply-to:mime-version
:content-type:references;
b=CbUpLvB9mtf4zNidsvgqw4EyOEbbLG1YaL3lWubFgyIW/7u1fl1tuLdYq0wY8RduN1
ycuPGwzYFNN9HqR4slTG2MnwTNe61Fkk/kOJLahPNJreKyOoCnTDT2N9l8/DAjIEhPG6
2bDZE5kZYNIr8MUW2taLrhixSbuX0IKwvGqic=
Received: by 10.214.45.12 with SMTP id s12mr9277711qas.0.1230163046705;
Wed, 24 Dec 2008 15:57:26 -0800 (PST)
Received: by 10.214.148.17 with HTTP; Wed, 24 Dec 2008 15:57:26 -0800 (PST)
Message-ID: <2a8d4a710812241557p3c9f9740me76323833131daaf@mail.gmail.com>
Date: Wed, 24 Dec 2008 18:57:26 -0500
From: "Matt Todd" <chiol...@gmail.com>
To: rack-devel@googlegroups.com
Subject: Re: Lazy-loaded and memoized processing
In-Reply-To: <1c5622660812241527t125930f2s2c04bb2e10be4...@mail.gmail.com>
MIME-Version: 1.0
Content-Type: multipart/alternative;
boundary="----=_Part_92697_22622930.1230163046701"
References: <245fb4700812241435j63e293b5q4f8d4f15af7cb...@mail.gmail.com>
<2a8d4a710812241456t156addf0ocf3ae51e7f226...@mail.gmail.com>
<1c5622660812241527t125930f2s2c04bb2e10be4...@mail.gmail.com>
------=_Part_92697_22622930.1230163046701
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Yeah, just ignored that for the sake of simplicity.
class Rack::Request
def self.new(env)
unless env['r']
env['r'] = super(env)
end
env['r']
end
def initialize(env); @env = env; end
end
I'll work on a patch tonight unless someone beats me to it.
Matt
On Wed, Dec 24, 2008 at 6:27 PM, Joshua Peek <j...@joshpeek.com> wrote:
>
> Tiny detail, override new for better backwords compat and a nicer API I
> think.
>
> On 12/24/08, Matt Todd <chiol...@gmail.com> wrote:
> > Effectively...
> >
> > def Rack::Request.from(env)
> > unless env['rack.request']
> > env['rack.request'] = Rack::Request.new(env)
> > end
> > env['rack.request']
> > end
> >
> > Hmm?
> >
> > Matt
> >
> >
> > On Wed, Dec 24, 2008 at 5:35 PM, Yehuda Katz <wyc...@gmail.com> wrote:
> >
> >> Hey guys. I just wanted to post about a problem I've been working
> through
> >> and a potential solution to get some feedback. Effectively, there's a
> >> bunch
> >> of related code that handles various processing of the Rack environment.
> >> However, much of this processing is triggered by requests by the user,
> and
> >> can be expensive. The current recommended approach is to create a
> >> middleware
> >> that processes the rack environment as needed, and stuff the results
> back
> >> into the environment hash. This works fine for cases where you know the
> >> processing will be needed, but not as well for cases where the
> processing
> >> is
> >> to be used optionally by a user downstream in the middleware chain.
> Before
> >> rack, the approach both Rails and Merb used was to do that processing in
> a
> >> Request object that could process the environment only when a specific
> >> accessor was called. Some examples include "method", a 10-line method in
> >> Merb, various parameter parsing (which can be quite expensive),
> remote_ip
> >> (another function that is longer than it seems like is reasonable), and
> it
> >> goes on and on. What is desirable is for the appropriate processing to
> be
> >> done when required, and only once. Whether or not the user is in the
> >> Rails/Merb application or Rack middleware should not affect this (the
> user
> >> should have access to any required processing). Unfortunately, since the
> >> Rack environment is required to be a "real" Hash, it's not possible to
> >> modify the environment to support lazy-loaded and memoized processing.
> One
> >> option we *considered* was a middleware that did something like
> >> env["rack.request_obj"] = Rack::Request.new(env). This would provide the
> >> benefits of a logical object for the request without breaking Rack
> >> conventions. However, after emailing Chris to explain this problem, he
> >> suggested an even better (to my eyes) solution: > I think I have a
> better
> >> idea for this... we could make > Rack::Request.new cache the request
> >> object
> >> in the env itself(!) and > just return it when it was created and
> >> calculated
> >> already. This would > be backward compatible, efficient, and not expose
> >> any
> >> details on the > implementation. I love this idea and would love to get
> >> some
> >> feedback on it. Thanks a ton,
> >>
> >> --
> >> Yehuda Katz
> >> Developer | Engine Yard
> >> (ph) 718.877.1325
> >>
> >
> >
> >
> > --
> > Matt Todd
> > Highgroove Studios
> > www.highgroove.com
> > cell: 404-314-2612
> > blog: maraby.org
> >
> > Scout - Web Monitoring and Reporting Software
> > www.scoutapp.com
> >
>
>
> --
> Joshua Peek
>
--
Matt Todd
Highgroove Studios
www.highgroove.com
cell: 404-314-2612
blog: maraby.org
Scout - Web Monitoring and Reporting Software
www.scoutapp.com
------=_Part_92697_22622930.1230163046701
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Yeah, just ignored that for the sake of simplicity.<div><br></div><div>class Rack::Request</div><div> def self.new(env)</div><div> unless env['r']</div><div> env['r'] = super(env)</div><div> end</div>
<div> env['r']</div><div> end</div><div> def initialize(env); @env = env; end</div><div>end<br></div><div><br></div><div>I'll work on a patch tonight unless someone beats me to it.</div><div><br></div><div>
Matt</div><div><br></div><div><br><br><div class="gmail_quote">On Wed, Dec 24, 2008 at 6:27 PM, Joshua Peek <span dir="ltr"><<a href="mailto:j...@joshpeek.com">j...@joshpeek.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
Tiny detail, override new for better backwords compat and a nicer API I think.<br>
<div><div></div><div class="Wj3C7c"><br>
On 12/24/08, Matt Todd <<a href="mailto:chiol...@gmail.com">chiol...@gmail.com</a>> wrote:<br>
> Effectively...<br>
><br>
> def Rack::Request.from(env)<br>
> unless env['rack.request']<br>
> env['rack.request'] = Rack::Request.new(env)<br>
> end<br>
> env['rack.request']<br>
> end<br>
><br>
> Hmm?<br>
><br>
> Matt<br>
><br>
><br>
> On Wed, Dec 24, 2008 at 5:35 PM, Yehuda Katz <<a href="mailto:wyc...@gmail.com">wyc...@gmail.com</a>> wrote:<br>
><br>
>> Hey guys. I just wanted to post about a problem I've been working through<br>
>> and a potential solution to get some feedback. Effectively, there's a<br>
>> bunch<br>
>> of related code that handles various processing of the Rack environment.<br>
>> However, much of this processing is triggered by requests by the user, and<br>
>> can be expensive. The current recommended approach is to create a<br>
>> middleware<br>
>> that processes the rack environment as needed, and stuff the results back<br>
>> into the environment hash. This works fine for cases where you know the<br>
>> processing will be needed, but not as well for cases where the processing<br>
>> is<br>
>> to be used optionally by a user downstream in the middleware chain. Before<br>
>> rack, the approach both Rails and Merb used was to do that processing in a<br>
>> Request object that could process the environment only when a specific<br>
>> accessor was called. Some examples include "method", a 10-line method in<br>
>> Merb, various parameter parsing (which can be quite expensive), remote_ip<br>
>> (another function that is longer than it seems like is reasonable), and it<br>
>> goes on and on. What is desirable is for the appropriate processing to be<br>
>> done when required, and only once. Whether or not the user is in the<br>
>> Rails/Merb application or Rack middleware should not affect this (the user<br>
>> should have access to any required processing). Unfortunately, since the<br>
>> Rack environment is required to be a "real" Hash, it's not possible to<br>
>> modify the environment to support lazy-loaded and memoized processing. One<br>
>> option we *considered* was a middleware that did something like<br>
>> env["rack.request_obj"] = Rack::Request.new(env). This would provide the<br>
>> benefits of a logical object for the request without breaking Rack<br>
>> conventions. However, after emailing Chris to explain this problem, he<br>
>> suggested an even better (to my eyes) solution: > I think I have a better<br>
>> idea for this... we could make > Rack::Request.new cache the request<br>
>> object<br>
>> in the env itself(!) and > just return it when it was created and<br>
>> calculated<br>
>> already. This would > be backward compatible, efficient, and not expose<br>
>> any<br>
>> details on the > implementation. I love this idea and would love to get<br>
>> some<br>
>> feedback on it. Thanks a ton,<br>
>><br>
>> --<br>
>> Yehuda Katz<br>
>> Developer | Engine Yard<br>
>> (ph) 718.877.1325<br>
>><br>
><br>
><br>
><br>
> --<br>
> Matt Todd<br>
> Highgroove Studios<br>
> <a href="http://www.highgroove.com" target="_blank">www.highgroove.com</a><br>
> cell: 404-314-2612<br>
> blog: <a href="http://maraby.org" target="_blank">maraby.org</a><br>
><br>
> Scout - Web Monitoring and Reporting Software<br>
> <a href="http://www.scoutapp.com" target="_blank">www.scoutapp.com</a><br>
><br>
<br>
<br>
</div></div>--<br>
<font color="#888888">Joshua Peek<br>
</font></blockquote></div><br><br clear="all"><br>-- <br>Matt Todd<br>Highgroove Studios<br><a href="http://www.highgroove.com">www.highgroove.com</a><br>cell: 404-314-2612<br>blog: <a href="http://maraby.org">maraby.org</a><br>
<br>Scout - Web Monitoring and Reporting Software<br><a href="http://www.scoutapp.com">www.scoutapp.com</a><br>
</div>
------=_Part_92697_22622930.1230163046701--