as much as I love Dancer, and I really truly do... as I said when I first used Dancer, it is a breath of fresh air in the world of Perl, Dancer has become really, really unreliable for me. The biggest problem that I face with it is the unreliable way I seem to get routes and layouts delivered to the browser. In my last email to this forum, I noted that I would get different layout than was expected. Today I decided to do a little experimentation. My routes are like so get '/video/:page_name/:movie' => sub { .. debug "using layout main_video"; layout 'main_video'; template 'video_mov', \%template_opts; }; get '/present/:page_name' => sub { .. debug "using layout main_presentation"; layout 'main_presentation'; template 'presentation_slides', \%template_opts; }; get '/*?' => sub { .. debug "using layout main"; template 'index', \%template_opts; } In my layouts I have also embedded debug strings like so <!-- main.tt --> <!-- main_presentation.tt --> <!-- main_video.tt --> Yet, when I go to a page that should be using the layout main, my log file says [88056] debug @0.001454> [hit #14]using layout main in .. yet, I can see using "View source" in the browser <!-- main_presentation.tt --> This is random, and it makes absolutely no sense. I would love to see this resolved, because, partly, I really, really love using Dancer. And, partly, I am sure there is nothing out there that is as easy and pleasurable to use. I shudder at the thought of going back to CGI::App, but I also can't let this unreliability continue. Suggestions? I am serving about 10 or 12 different apps using Starman proxied behind Apache2, if that is any help. -- Puneet Kishor
On 20/10/11 2:51 PM, Mr. Puneet Kishor wrote:
Suggestions? I am serving about 10 or 12 different apps using Starman proxied behind Apache2, if that is any help.
Hi Puneet, Have you tried setting the layout in the template call ? ... template 'video_mov', \%template_opts, { layout => 'main_video' }; ... template 'presentation_slides', \%template_opts, { layout => layout 'main_presentation' }; This is they way I tend to do it, albeit not behind Apache, and have not had any troubles thus far. Cheers Matt
On Oct 19, 2011, at 11:46 PM, Matthew Vickers wrote:
On 20/10/11 2:51 PM, Mr. Puneet Kishor wrote:
Suggestions? I am serving about 10 or 12 different apps using Starman proxied behind Apache2, if that is any help.
Hi Puneet,
Have you tried setting the layout in the template call ?
...
template 'video_mov', \%template_opts, { layout => 'main_video' };
...
template 'presentation_slides', \%template_opts, { layout => layout 'main_presentation' };
hmmmm... so you are implying that perhaps having a separate `layout 'main_presentation'` is not enough? Or, are you implying that even though I have `layout 'main_presentation'` in the presentation route, and `layout 'main_video'` in the video route, perhaps I am seeing these problems because I don't have `layout 'main'` in my regular route? In any case, I have changed my code per your instructions above. Will check and report to see if the problem has gone away. Well, since the problem was seeming random, I can't ever check the absence of the problem. But, I will report back if the problem comes back. Many thanks Matthew. Hoping this works. I've a lot riding on Dancer. Actually, at some point I will like to submit my apps to the Dancer gallery of apps. Most of them are scientific data serving apps with RESTful data services, and Dancer is getting a full workout. Would be a good testament. Puneet.
On Thu, Oct 20, 2011 at 9:36 AM, Mr. Puneet Kishor <punk.kish@gmail.com> wrote:
On Oct 19, 2011, at 11:46 PM, Matthew Vickers wrote:
On 20/10/11 2:51 PM, Mr. Puneet Kishor wrote:
Suggestions? I am serving about 10 or 12 different apps using Starman proxied behind Apache2, if that is any help.
Hi Puneet,
Have you tried setting the layout in the template call ?
...
template 'video_mov', \%template_opts, { layout => 'main_video' };
...
template 'presentation_slides', \%template_opts, { layout => layout 'main_presentation' };
hmmmm... so you are implying that perhaps having a separate `layout 'main_presentation'` is not enough? Or, are you implying that even though I have `layout 'main_presentation'` in the presentation route, and `layout 'main_video'` in the video route, perhaps I am seeing these problems because I don't have `layout 'main'` in my regular route?
I think he was saying that you might have code in your apps such as: set layout => 'foo'; This would set the layout globally and might have been the cause of your issue. -Naveed
In any case, I have changed my code per your instructions above. Will check and report to see if the problem has gone away. Well, since the problem was seeming random, I can't ever check the absence of the problem. But, I will report back if the problem comes back.
Many thanks Matthew. Hoping this works. I've a lot riding on Dancer.
Actually, at some point I will like to submit my apps to the Dancer gallery of apps. Most of them are scientific data serving apps with RESTful data services, and Dancer is getting a full workout. Would be a good testament.
Puneet.
On Oct 20, 2011, at 10:47 AM, Naveed Massjouni wrote:
On Thu, Oct 20, 2011 at 9:36 AM, Mr. Puneet Kishor <punk.kish@gmail.com> wrote:
On Oct 19, 2011, at 11:46 PM, Matthew Vickers wrote:
On 20/10/11 2:51 PM, Mr. Puneet Kishor wrote:
Suggestions? I am serving about 10 or 12 different apps using Starman proxied behind Apache2, if that is any help.
Hi Puneet,
Have you tried setting the layout in the template call ?
...
template 'video_mov', \%template_opts, { layout => 'main_video' };
...
template 'presentation_slides', \%template_opts, { layout => layout 'main_presentation' };
hmmmm... so you are implying that perhaps having a separate `layout 'main_presentation'` is not enough? Or, are you implying that even though I have `layout 'main_presentation'` in the presentation route, and `layout 'main_video'` in the video route, perhaps I am seeing these problems because I don't have `layout 'main'` in my regular route?
I think he was saying that you might have code in your apps such as: set layout => 'foo'; This would set the layout globally and might have been the cause of your issue.
In that case, no, I never used `set layout => 'foo'` anywhere in my code. Only within specific routes, I used `layout 'foo'`. So, one, IFF `layout 'foo'` has the same effect as `set layout => 'foo'`, even then it shouldn't have mattered, because every route is doing its own `layout 'foo'`. In other words, even if me or some other user requests a route that does `layout 'foo'`, when me or the other user requests a route with a different layout, that route has its own `layout 'bar'`. I don't see how even cross browser or cross computer invocations could affect. Well, I will keep an eye on the app and see if the problem recurs after having implemented Matthew Vickers' suggestion. -- Puneet Kishor
On Thu, Oct 20, 2011 at 9:13 AM, Mr. Puneet Kishor <punk.kish@gmail.com>wrote:
On Oct 20, 2011, at 10:47 AM, Naveed Massjouni wrote:
On Thu, Oct 20, 2011 at 9:36 AM, Mr. Puneet Kishor <punk.kish@gmail.com> wrote:
On Oct 19, 2011, at 11:46 PM, Matthew Vickers wrote:
On 20/10/11 2:51 PM, Mr. Puneet Kishor wrote:
Suggestions? I am serving about 10 or 12 different apps using Starman
proxied behind Apache2, if that is any help.
Hi Puneet,
Have you tried setting the layout in the template call ?
...
template 'video_mov', \%template_opts, { layout => 'main_video' };
...
template 'presentation_slides', \%template_opts, { layout => layout 'main_presentation' };
hmmmm... so you are implying that perhaps having a separate `layout 'main_presentation'` is not enough? Or, are you implying that even though I have `layout 'main_presentation'` in the presentation route, and `layout 'main_video'` in the video route, perhaps I am seeing these problems because I don't have `layout 'main'` in my regular route?
I think he was saying that you might have code in your apps such as: set layout => 'foo'; This would set the layout globally and might have been the cause of your issue.
In that case, no, I never used `set layout => 'foo'` anywhere in my code. Only within specific routes, I used `layout 'foo'`. So, one, IFF `layout 'foo'` has the same effect as `set layout => 'foo'`, even then it shouldn't have mattered, because every route is doing its own `layout 'foo'`. In other words, even if me or some other user requests a route that does `layout 'foo'`, when me or the other user requests a route with a different layout, that route has its own `layout 'bar'`. I don't see how even cross browser or cross computer invocations could affect.
If it's a global variable, isn't it possible that you can set it in one route and then a concurrent request to another resource can overwrite it between the time you set it and the time you use it?
Well, I will keep an eye on the app and see if the problem recurs after having implemented Matthew Vickers' suggestion.
-- Puneet Kishor
_______________________________________________ Dancer-users mailing list Dancer-users@perldancer.org http://www.backup-manager.org/cgi-bin/listinfo/dancer-users
On Oct 20, 2011, at 11:15 AM, Brian E. Lozier wrote:
On Thu, Oct 20, 2011 at 9:13 AM, Mr. Puneet Kishor <punk.kish@gmail.com>wrote:
On Oct 20, 2011, at 10:47 AM, Naveed Massjouni wrote:
On Thu, Oct 20, 2011 at 9:36 AM, Mr. Puneet Kishor <punk.kish@gmail.com> wrote:
On Oct 19, 2011, at 11:46 PM, Matthew Vickers wrote:
On 20/10/11 2:51 PM, Mr. Puneet Kishor wrote:
Suggestions? I am serving about 10 or 12 different apps using Starman
proxied behind Apache2, if that is any help.
Hi Puneet,
Have you tried setting the layout in the template call ?
...
template 'video_mov', \%template_opts, { layout => 'main_video' };
...
template 'presentation_slides', \%template_opts, { layout => layout 'main_presentation' };
hmmmm... so you are implying that perhaps having a separate `layout 'main_presentation'` is not enough? Or, are you implying that even though I have `layout 'main_presentation'` in the presentation route, and `layout 'main_video'` in the video route, perhaps I am seeing these problems because I don't have `layout 'main'` in my regular route?
I think he was saying that you might have code in your apps such as: set layout => 'foo'; This would set the layout globally and might have been the cause of your issue.
In that case, no, I never used `set layout => 'foo'` anywhere in my code. Only within specific routes, I used `layout 'foo'`. So, one, IFF `layout 'foo'` has the same effect as `set layout => 'foo'`, even then it shouldn't have mattered, because every route is doing its own `layout 'foo'`. In other words, even if me or some other user requests a route that does `layout 'foo'`, when me or the other user requests a route with a different layout, that route has its own `layout 'bar'`. I don't see how even cross browser or cross computer invocations could affect.
If it's a global variable, isn't it possible that you can set it in one route and then a concurrent request to another resource can overwrite it between the time you set it and the time you use it?
sure, but that is only if my own request came from a route that didn't implement a layout. What I am saying is -- - I don't have any layout being set outside of a route; and - all my routes are setting a layout So, at the instant that my query hits the server, the application figures out the route for me. In the process of doing so, the application learns of the template to use for that route, because when it goes through the code for that route, and does all the other stuff such as getting the data for that route and assembling it into a web page, it also learns of the specific layout to use. Hmmm... are you saying that *after* my request has figured out the route to use but *before* is has assembled it using the layout for that route, someone else queried a different route in my application and, thus, reset the layout to a different layout? Vaguely possible, but heck, this is my personal web site... not amazon.com. About 3 people a year visit it. If I keep refreshing my browser by hitting Cmd-R, I keep on getting the wrong layout. Maybe this is because of some global setting, but somehow methinks there is something funky in the routes-choosing mechanism... or, maybe it is something that I have no idea about. -- Puneet Kishor
On 20/10/11 17:13, Mr. Puneet Kishor wrote:
On Oct 20, 2011, at 10:47 AM, Naveed Massjouni wrote:
I think he was saying that you might have code in your apps such as: set layout => 'foo'; This would set the layout globally and might have been the cause of your issue.
In that case, no, I never used `set layout => 'foo'` anywhere in my code. Only within specific routes, I used `layout 'foo'`.
But in your original example you had this:
get '/*?' => sub { .. debug "using layout main"; template 'index', \%template_opts; }
That will end up with whatever layout the previous request set. The layout is *not* per-request (unless you add it to the template call). -- Richard Huxton Archonet Ltd
On Oct 20, 2011, at 11:22 AM, Richard Huxton wrote:
On 20/10/11 17:13, Mr. Puneet Kishor wrote:
On Oct 20, 2011, at 10:47 AM, Naveed Massjouni wrote:
I think he was saying that you might have code in your apps such as: set layout => 'foo'; This would set the layout globally and might have been the cause of your issue.
In that case, no, I never used `set layout => 'foo'` anywhere in my code. Only within specific routes, I used `layout 'foo'`.
But in your original example you had this:
get '/*?' => sub { .. debug "using layout main"; template 'index', \%template_opts; }
That will end up with whatever layout the previous request set.
The layout is *not* per-request (unless you add it to the template call).
Yes, this is the *only* potential problem spot that I could see, and I mentioned that in my subsequent email. I have not added a layout even to the default route instead of relying on the 'main' layout to be picked up automatically. Here is the funny thing though -- I tested for that as well (yesterday, before I added the new code today). I requested a page which sent back the default layout correctly. Then I requested the page that sent back 'main_presentation' correctly. Then I requested the page with the default layout and that also came back correctly. In other words, I was unable to force an erroneous layout. And then, 10 mins later, bam, I requested the default page but it came back with the presentation layout. Then I hit Cmd-R 10 times and got the presentation layout (wrong layout) and then suddenly, bam, it reverted back to the default layout. In fact, think this through -- if the above is really true, then once the non-default layout has been set (say, 'main_presentation') then the default 'main' layout should never be set for anyone because I wasn't explicitly setting the main layout. But, that wasn't the case as well. I may never know the answer, but I can only hope that I don't encounter this unpredictable behavior. -- Puneet Kishor
On 20/10/11 17:28, Mr. Puneet Kishor wrote:
On Oct 20, 2011, at 11:22 AM, Richard Huxton wrote:
That will end up with whatever layout the previous request set.
The layout is *not* per-request (unless you add it to the template call).
Yes, this is the *only* potential problem spot that I could see, and I mentioned that in my subsequent email. I have not added a layout even to the default route instead of relying on the 'main' layout to be picked up automatically. [snip] In other words, I was unable to force an erroneous layout. And then, 10 mins later, bam, I requested the default page but it came back with the presentation layout. Then I hit Cmd-R 10 times and got the presentation layout (wrong layout) and then suddenly, bam, it reverted back to the default layout.
If you have more than one backend (e.g. Starman, or a dynamic fastCGI setup), then that's quite likely. The best way to see it would be something like: before sub { debug "before ($$): layout = ".setting('layout') ." path = ".request->path; }; after sub { debug "after ($$): layout = ".setting('layout') ." path = ".request->path; }; That will show you the backend process-id and layout before + after rendering. If there's anything funny going on then that's where it is.
In fact, think this through -- if the above is really true, then once the non-default layout has been set (say, 'main_presentation') then the default 'main' layout should never be set for anyone because I wasn't explicitly setting the main layout. But, that wasn't the case as well.
Well, it'll be set if that backend hasn't changed it yet, because that's what it defaults to (I assume). But, if you've only got one backend then you're correct. -- Richard Huxton Archonet Ltd
On Oct 20, 2011, at 1:40 PM, Richard Huxton wrote:
..
In fact, think this through -- if the above is really true, then once the non-default layout has been set (say, 'main_presentation') then the default 'main' layout should never be set for anyone because I wasn't explicitly setting the main layout. But, that wasn't the case as well.
Well, it'll be set if that backend hasn't changed it yet, because that's what it defaults to (I assume). But, if you've only got one backend then you're correct.
Just one backend. All my apps are with Starman serving on http://127.0.0.1:<port> proxied behind Apache VirtualHost front ends. -- Puneet Kishor
On 20/10/11 20:05, Puneet Kishor wrote:
On Oct 20, 2011, at 1:40 PM, Richard Huxton wrote:
In fact, think this through -- if the above is really true, then once the non-default layout has been set (say, 'main_presentation') then the default 'main' layout should never be set for anyone because I wasn't explicitly setting the main layout. But, that wasn't the case as well.
Well, it'll be set if that backend hasn't changed it yet, because that's what it defaults to (I assume). But, if you've only got one backend then you're correct.
Just one backend. All my apps are with Starman serving on http://127.0.0.1:<port> proxied behind Apache VirtualHost front ends.
Sorry - we're using different terminology. Starman has a --workers option which you usually set to something greater than 1. Each one will have its own settings (including the "layout" setting). Each request can go to a different worker. So you can end up with: request 1: login page - worker 1 - sets layout = nomenu request 2: home page - worker 2 - sets layout = menu request 3: news page - worker 1 - will start with layout=nomenu Now, if request 3 had gone to worker 2 you would have had a default layout of "menu" instead. I think this is what you are seeing, you can see how if you've got 10 workers the situation can get confusing. -- Richard Huxton Archonet Ltd
On Oct 20, 2011, at 2:50 PM, Richard Huxton wrote:
On 20/10/11 20:05, Puneet Kishor wrote:
On Oct 20, 2011, at 1:40 PM, Richard Huxton wrote:
In fact, think this through -- if the above is really true, then once the non-default layout has been set (say, 'main_presentation') then the default 'main' layout should never be set for anyone because I wasn't explicitly setting the main layout. But, that wasn't the case as well.
Well, it'll be set if that backend hasn't changed it yet, because that's what it defaults to (I assume). But, if you've only got one backend then you're correct.
Just one backend. All my apps are with Starman serving on http://127.0.0.1:<port> proxied behind Apache VirtualHost front ends.
Sorry - we're using different terminology. Starman has a --workers option which you usually set to something greater than 1. Each one will have its own settings (including the "layout" setting). Each request can go to a different worker. So you can end up with: request 1: login page - worker 1 - sets layout = nomenu request 2: home page - worker 2 - sets layout = menu request 3: news page - worker 1 - will start with layout=nomenu
Now, if request 3 had gone to worker 2 you would have had a default layout of "menu" instead. I think this is what you are seeing, you can see how if you've got 10 workers the situation can get confusing.
This is brilliant information. I never made this connection. Thanks a ton for this as this will allow me to be more careful with the way I code my apps. I guess the main thing is to be as specific as possible vis a vis routes and templates. -- Puneet Kishor
On 20/10/11 21:57, Puneet Kishor wrote:
On Oct 20, 2011, at 2:50 PM, Richard Huxton wrote:
Sorry - we're using different terminology. Starman has a --workers option which you usually set to something greater than 1. Each one will have its own settings (including the "layout" setting). Each request can go to a different worker. So you can end up with: request 1: login page - worker 1 - sets layout = nomenu request 2: home page - worker 2 - sets layout = menu request 3: news page - worker 1 - will start with layout=nomenu
Now, if request 3 had gone to worker 2 you would have had a default layout of "menu" instead. I think this is what you are seeing, you can see how if you've got 10 workers the situation can get confusing.
This is brilliant information. I never made this connection. Thanks a ton for this as this will allow me to be more careful with the way I code my apps. I guess the main thing is to be as specific as possible vis a vis routes and templates.
Whenever you have more than one context for your data, or more than one worker operating on it you need to be careful with this sort of thing. There are two different axes you need to think about it: lexical scope - per function - per module - per backend - global (e.g. session storage, databases) temporal scope - per request (dancer params) - per session (dancer sessions) - per backend lifetime (our $var) - long-term (databases) If some value (like layout) isn't in the grid you think it is, you get unexpected behaviour. Likewise putting information in the wrong grid (e.g. "current client" isn't session-based) can cause problems. You'll get similar unexpected behaviour when you have concurrency issues with multiple workers operating on shared data. What works fine with a single worker can intermittently fail with multiple ones. -- Richard Huxton Archonet Ltd
Whenever you have more than one context for your data, or more than one worker operating on it you need to be careful with this sort of thing.
There are two different axes you need to think about it: lexical scope - per function - per module - per backend - global (e.g. session storage, databases) temporal scope - per request (dancer params) - per session (dancer sessions) - per backend lifetime (our $var) - long-term (databases)
If some value (like layout) isn't in the grid you think it is, you get
unexpected behaviour. Likewise putting information in the wrong grid (e.g. "current client" isn't session-based) can cause problems.
You'll get similar unexpected behaviour when you have concurrency issues with multiple workers operating on shared data. What works fine with a
single worker can intermittently fail with multiple ones.
Brilliant advice, thanks Richard ! Matt -- www.quispiam.com | filtosaur.com +61 405001707
On 20/10/11 04:51, Mr. Puneet Kishor wrote:
In my last email to this forum, I noted that I would get different layout than was expected. Today I decided to do a little experimentation.
This caught me out too. The "set layout" changes a setting, and it's persistent. So - once it's set it stays set for any further requests, until you set it to something else. Which, if you're trying to use it like you are (and I did) is not helpful. Mathhew's recommendation is right - add an options hashref to the template call and you can set it just for that template (which is what I usually want). Why have it the other way? Presumably it's useful if you want to switch layouts because e.g. the user is viewing the site from their phone, or has chosen an accessible layout etc. -- Richard Huxton Archonet Ltd
Hello, 2011/10/20 Mr. Puneet Kishor <punk.kish@gmail.com>:
as much as I love Dancer, and I really truly do... as I said when I first used Dancer, it is a breath of fresh air in the world of Perl, Dancer has become really, really unreliable for me. [...] get '/video/:page_name/:movie' => sub { .. debug "using layout main_video"; layout 'main_video'; template 'video_mov', \%template_opts; };
You're doing it wrong. It's not "unreliable", it's just that you're using a setting (which is global and persistent) as a pramater for a route response (which is supposed to be scopped to the request it's responding to). If you want to use (or change) the layout to be used for a specific template call, then you should use the option provided for doing so. See perldoc Dancer ("template").
participants (7)
-
Alexis Sukrieh -
Brian E. Lozier -
Matthew Vickers -
Mr. Puneet Kishor -
Naveed Massjouni -
Puneet Kishor -
Richard Huxton