mysterious behavior putting Dancer app in production on Starman
Check out the following [http://teststrata.geology.wisc.edu/macromap]. It should be working -- it should show a Google map backdrop with a bunch of polygons and a few points. As you pan and zoom, polys and points for the new viewport should be retrieved. The polys and points are retrieved via ajax from [http://teststrata.geology.wisc.edu/mstrat/] that is serving them from a MySQL db as a REST service. Both apps are Dancer based, and are running on Starman using the following invocation $ plackup -p <port> -E production -s Starman -w 10 -a bin/app.pl The first app (macromap) also has the -D switch added to the above plackup command so plackup runs in the background as a daemon (or a faceless app, or whatever is the correct terminology). Here is the interesting thing -- if I add the -D switch to the second app as well, it fails to return the polys and the points. It fails with the error {"error":"Warning caught during route execution: DBD::mysql::st fetchall_arrayref failed: fetch() without execute() at <path/to>/macrostrat.pm line 79.\n"} The offending lines are 71> my $sql = qq{ 72> .. 73> 74> 75> }; 76> 77> my $sth = $dbh->prepare($sql); 78> $sth->execute(); 79> my $res = $sth->fetchall_arrayref({}); The above could be just correlation rather than causal, but it definitely seems to be a pattern. First, this is bizarre, and why so? And, two... this is totally bogus... how can execute() not take place above? Perl doesn't have a habit of jumping over lines, does it? Absolutely mystified in Madison. Puneet.
If you set DBI_TRACE=1, you may get some useful info e.g.: $ export DBI_TRACE=1 Kind regards, Paul Findlay DISCLAIMER This email contains information that is confidential and which may be legally privileged. If you have received this email in error, please notify the sender immediately and delete the email. This email is intended solely for the use of the intended recipient and you may not use or disclose this email in any way.
On Jul 14, 2011, at 8:55 PM, Mr. Puneet Kishor wrote:
Check out the following [http://teststrata.geology.wisc.edu/macromap]. It should be working -- it should show a Google map backdrop with a bunch of polygons and a few points. As you pan and zoom, polys and points for the new viewport should be retrieved.
The polys and points are retrieved via ajax from [http://teststrata.geology.wisc.edu/mstrat/] that is serving them from a MySQL db as a REST service.
Both apps are Dancer based, and are running on Starman using the following invocation
$ plackup -p <port> -E production -s Starman -w 10 -a bin/app.pl
The first app (macromap) also has the -D switch added to the above plackup command so plackup runs in the background as a daemon (or a faceless app, or whatever is the correct terminology).
Here is the interesting thing -- if I add the -D switch to the second app as well, it fails to return the polys and the points. It fails with the error
{"error":"Warning caught during route execution: DBD::mysql::st fetchall_arrayref failed: fetch() without execute() at <path/to>/macrostrat.pm line 79.\n"}
The offending lines are
71> my $sql = qq{ 72> .. 73> 74> 75> }; 76> 77> my $sth = $dbh->prepare($sql); 78> $sth->execute(); 79> my $res = $sth->fetchall_arrayref({});
The above could be just correlation rather than causal, but it definitely seems to be a pattern. First, this is bizarre, and why so? And, two... this is totally bogus... how can execute() not take place above? Perl doesn't have a habit of jumping over lines, does it?
Absolutely mystified in Madison.
Following Paul Findlay's advice, I launched my offending app with the following invocation $DBI_TRACE=2=logs/dbi.log plackup -E production -p 5001 -s Starman -w 10 -a bin/app.pl And, following is what stood out to me as the potential culprit in the log file > Handle is not in asynchronous mode error 2000 recorded: Handle is > not in asynchronous mode > !! ERROR: 2000 CLEARED by call to fetch method (I am shooting in the dark here) I believe Dancer uses a lot of global variables. Would that be connected to this error? On occasion, I am also seeing another mysterious behavior, so mysterious that I feel I am smoking something -- One request to the web server pulls in points, and another request pulls in polys. They are called like so http://webserver/points.json http://webserver/polys.json They are both separate asynchronous requests, sent via separate $.ajax() jQuery calls from the browser. On occasion, and I swear I am not making this up, I see points json stream returned via the polys request. Of course, because points.json returns different data than polys.json, I get an error. For what its worth, and this is highly unscientific, this doesn't happen if plackup is in `-E development` mode. It only happens in the `-E production -D` mode. But, I could be wrong about this as I don't have a large enough sample set to confirm this finding conclusively. Thoughts?
Following with more investigation and observation (please see below) -- On Jul 15, 2011, at 9:07 AM, Mr. Puneet Kishor wrote:
On Jul 14, 2011, at 8:55 PM, Mr. Puneet Kishor wrote:
Check out the following [http://teststrata.geology.wisc.edu/macromap]. It should be working -- it should show a Google map backdrop with a bunch of polygons and a few points. As you pan and zoom, polys and points for the new viewport should be retrieved.
The polys and points are retrieved via ajax from [http://teststrata.geology.wisc.edu/mstrat/] that is serving them from a MySQL db as a REST service.
Both apps are Dancer based, and are running on Starman using the following invocation
$ plackup -p <port> -E production -s Starman -w 10 -a bin/app.pl
The first app (macromap) also has the -D switch added to the above plackup command so plackup runs in the background as a daemon (or a faceless app, or whatever is the correct terminology).
Here is the interesting thing -- if I add the -D switch to the second app as well, it fails to return the polys and the points. It fails with the error
{"error":"Warning caught during route execution: DBD::mysql::st fetchall_arrayref failed: fetch() without execute() at <path/to>/macrostrat.pm line 79.\n"}
The offending lines are
71> my $sql = qq{ 72> .. 73> 74> 75> }; 76> 77> my $sth = $dbh->prepare($sql); 78> $sth->execute(); 79> my $res = $sth->fetchall_arrayref({});
The above could be just correlation rather than causal, but it definitely seems to be a pattern. First, this is bizarre, and why so? And, two... this is totally bogus... how can execute() not take place above? Perl doesn't have a habit of jumping over lines, does it?
Absolutely mystified in Madison.
Following Paul Findlay's advice, I launched my offending app with the following invocation
$DBI_TRACE=2=logs/dbi.log plackup -E production -p 5001 -s Starman -w 10 -a bin/app.pl
And, following is what stood out to me as the potential culprit in the log file
Handle is not in asynchronous mode error 2000 recorded: Handle is not in asynchronous mode !! ERROR: 2000 CLEARED by call to fetch method
(I am shooting in the dark here) I believe Dancer uses a lot of global variables. Would that be connected to this error? On occasion, I am also seeing another mysterious behavior, so mysterious that I feel I am smoking something --
One request to the web server pulls in points, and another request pulls in polys. They are called like so
http://webserver/points.json http://webserver/polys.json
They are both separate asynchronous requests, sent via separate $.ajax() jQuery calls from the browser. On occasion, and I swear I am not making this up, I see points json stream returned via the polys request. Of course, because points.json returns different data than polys.json, I get an error.
For what its worth, and this is highly unscientific, this doesn't happen if plackup is in `-E development` mode. It only happens in the `-E production -D` mode. But, I could be wrong about this as I don't have a large enough sample set to confirm this finding conclusively.
Thoughts?
A simple script like so works like a champ... no async nonsense, no errors. All 1000 requests are effortlessly returned by the same set up. use LWP::UserAgent; my $BBOX = "-96.09299316406248+38.96034339396338%2C+83.39279785156248+38.96034339396338%2C+-83.39279785156248+44.33256692562997%2C+96.09299316406248+44.33256692562997%2C+-96.09299316406248+38.96034339396338"; for (1 .. 1000) { open my $fh, ">>", 'foo.txt'; my $ua = LWP::UserAgent->new; $ua->agent("MyApp/0.1 "); my $req = HTTP::Request->new(GET => "http://localhost:5001/points.json?callback=foo&BBOX=$BBOX"); my $res = $ua->request($req); # Check the outcome of the response if ($res->is_success) { say $fh $res->content; } else { say $fh $res->status_line; } close $fh; } So, it seems that both MySQL and Starman are very capable of handling this. The only element missing here is Dancer, and the browser. Thoughts anyone? I am just interested in finding out the issues here, and creating a robust, workable app. Many thanks in advance. Puneet.
Knock knock? Anyone, any ideas? I realize not much time has passed since I posted this, but I have until tomorrow to get a concept demo ready. So, I have to decide today whether or not to continue on this path or cut bait. On Jul 16, 2011, at 8:05 PM, Mr. Puneet Kishor <punk.kish@gmail.com> wrote:
Following with more investigation and observation (please see below) --
On Jul 15, 2011, at 9:07 AM, Mr. Puneet Kishor wrote:
On Jul 14, 2011, at 8:55 PM, Mr. Puneet Kishor wrote:
Check out the following [http://teststrata.geology.wisc.edu/macromap]. It should be working -- it should show a Google map backdrop with a bunch of polygons and a few points. As you pan and zoom, polys and points for the new viewport should be retrieved.
The polys and points are retrieved via ajax from [http://teststrata.geology.wisc.edu/mstrat/] that is serving them from a MySQL db as a REST service.
Both apps are Dancer based, and are running on Starman using the following invocation
$ plackup -p <port> -E production -s Starman -w 10 -a bin/app.pl
The first app (macromap) also has the -D switch added to the above plackup command so plackup runs in the background as a daemon (or a faceless app, or whatever is the correct terminology).
Here is the interesting thing -- if I add the -D switch to the second app as well, it fails to return the polys and the points. It fails with the error
{"error":"Warning caught during route execution: DBD::mysql::st fetchall_arrayref failed: fetch() without execute() at <path/to>/macrostrat.pm line 79.\n"}
The offending lines are
71> my $sql = qq{ 72> .. 73> 74> 75> }; 76> 77> my $sth = $dbh->prepare($sql); 78> $sth->execute(); 79> my $res = $sth->fetchall_arrayref({});
The above could be just correlation rather than causal, but it definitely seems to be a pattern. First, this is bizarre, and why so? And, two... this is totally bogus... how can execute() not take place above? Perl doesn't have a habit of jumping over lines, does it?
Absolutely mystified in Madison.
Following Paul Findlay's advice, I launched my offending app with the following invocation
$DBI_TRACE=2=logs/dbi.log plackup -E production -p 5001 -s Starman -w 10 -a bin/app.pl
And, following is what stood out to me as the potential culprit in the log file
Handle is not in asynchronous mode error 2000 recorded: Handle is not in asynchronous mode !! ERROR: 2000 CLEARED by call to fetch method
(I am shooting in the dark here) I believe Dancer uses a lot of global variables. Would that be connected to this error? On occasion, I am also seeing another mysterious behavior, so mysterious that I feel I am smoking something --
One request to the web server pulls in points, and another request pulls in polys. They are called like so
http://webserver/points.json http://webserver/polys.json
They are both separate asynchronous requests, sent via separate $.ajax() jQuery calls from the browser. On occasion, and I swear I am not making this up, I see points json stream returned via the polys request. Of course, because points.json returns different data than polys.json, I get an error.
For what its worth, and this is highly unscientific, this doesn't happen if plackup is in `-E development` mode. It only happens in the `-E production -D` mode. But, I could be wrong about this as I don't have a large enough sample set to confirm this finding conclusively.
Thoughts?
A simple script like so works like a champ... no async nonsense, no errors. All 1000 requests are effortlessly returned by the same set up.
use LWP::UserAgent;
my $BBOX = "-96.09299316406248+38.96034339396338%2C+83.39279785156248+38.96034339396338%2C+-83.39279785156248+44.33256692562997%2C+96.09299316406248+44.33256692562997%2C+-96.09299316406248+38.96034339396338";
for (1 .. 1000) { open my $fh, ">>", 'foo.txt';
my $ua = LWP::UserAgent->new; $ua->agent("MyApp/0.1 ");
my $req = HTTP::Request->new(GET => "http://localhost:5001/points.json?callback=foo&BBOX=$BBOX"); my $res = $ua->request($req);
# Check the outcome of the response if ($res->is_success) { say $fh $res->content; } else { say $fh $res->status_line; }
close $fh; }
So, it seems that both MySQL and Starman are very capable of handling this. The only element missing here is Dancer, and the browser. Thoughts anyone? I am just interested in finding out the issues here, and creating a robust, workable app.
Many thanks in advance.
Puneet.
On Sunday 17 July 2011 15:58:39 Mr. Puneet Kishor wrote:
Knock knock? Anyone, any ideas? I realize not much time has passed since I posted this, but I have until tomorrow to get a concept demo ready. So, I have to decide today whether or not to continue on this path or cut bait.
I see no obvious reason for the problems you're having. Is the full code available anywhere to view?
On Jul 17, 2011, at 10:36 AM, David Precious wrote:
On Sunday 17 July 2011 15:58:39 Mr. Puneet Kishor wrote:
Knock knock? Anyone, any ideas? I realize not much time has passed since I posted this, but I have until tomorrow to get a concept demo ready. So, I have to decide today whether or not to continue on this path or cut bait.
I see no obvious reason for the problems you're having.
Is the full code available anywhere to view?
See http://pastebin.com/eknBqRjk for the JavaScript code that makes the Ajax calls. And, http://pastebin.com/nWjGVBWb for the Dancer code. Thanks for the help. Puneet.
Top posting a solution -- I think I may have found a reason and a (temporary) solution. Actually, I didn't find it, but a helpful person at Stackoverflow suggested that I may be creating a $dbh that might be getting shared by different Starman preforked children (see link below). I think that was the case. I am still testing it by moving the $dbh creation in the subs. http://stackoverflow.com/questions/6721057/asynchronous-queries-with-mysql-p... So, instead of package mypackage; use Dancer ':syntax'; use DBI; my $dbh = DBI->connect(".."); get '/' => sub { template 'index'; }; get '/points.:format' => sub { my $bbox = params->{'BBOX'}; my $callback = params->{'callback'}; return $callback . '(' . to_json(points_within_bbox($bbox)) . ')'; }; get '/polys.:format' => sub { my $bbox = params->{'BBOX'}; my $callback = params->{'callback'}; return $callback . '(' . to_json(polys_within_bbox($bbox)) . ')'; }; sub points_within_bbox { my ($bbox) = @_; my $sth = $dbh->prepare(".."); $sth->execute($bbox); return $sth->fetchall_arrayref({}); } sub polys_within_bbox { my ($bbox) = @_; my $sth = $dbh->prepare(".."); $sth->execute($bbox); return $sth->fetchall_arrayref({}); } I now do the following package mypackage; use Dancer ':syntax'; use DBI; get '/' => sub { template 'index'; }; get '/points.:format' => sub { my $bbox = params->{'BBOX'}; my $callback = params->{'callback'}; return $callback . '(' . to_json(points_within_bbox($bbox)) . ')'; }; get '/polys.:format' => sub { my $bbox = params->{'BBOX'}; my $callback = params->{'callback'}; return $callback . '(' . to_json(polys_within_bbox($bbox)) . ')'; }; sub points_within_bbox { my ($bbox) = @_; my $dbh = DBI->connect(".."); my $sth = $dbh->prepare(".."); $sth->execute($bbox); return $sth->fetchall_arrayref({}); } sub polys_within_bbox { my ($bbox) = @_; my $dbh = DBI->connect(".."); my $sth = $dbh->prepare(".."); $sth->execute($bbox); return $sth->fetchall_arrayref({}); } It seems to be holding up. I am going to add another web service to the app, and see if it works. On Jul 16, 2011, at 8:05 PM, Mr. Puneet Kishor wrote:
Following with more investigation and observation (please see below) --
On Jul 15, 2011, at 9:07 AM, Mr. Puneet Kishor wrote:
On Jul 14, 2011, at 8:55 PM, Mr. Puneet Kishor wrote:
Check out the following [http://teststrata.geology.wisc.edu/macromap]. It should be working -- it should show a Google map backdrop with a bunch of polygons and a few points. As you pan and zoom, polys and points for the new viewport should be retrieved.
The polys and points are retrieved via ajax from [http://teststrata.geology.wisc.edu/mstrat/] that is serving them from a MySQL db as a REST service.
Both apps are Dancer based, and are running on Starman using the following invocation
$ plackup -p <port> -E production -s Starman -w 10 -a bin/app.pl
The first app (macromap) also has the -D switch added to the above plackup command so plackup runs in the background as a daemon (or a faceless app, or whatever is the correct terminology).
Here is the interesting thing -- if I add the -D switch to the second app as well, it fails to return the polys and the points. It fails with the error
{"error":"Warning caught during route execution: DBD::mysql::st fetchall_arrayref failed: fetch() without execute() at <path/to>/macrostrat.pm line 79.\n"}
The offending lines are
71> my $sql = qq{ 72> .. 73> 74> 75> }; 76> 77> my $sth = $dbh->prepare($sql); 78> $sth->execute(); 79> my $res = $sth->fetchall_arrayref({});
The above could be just correlation rather than causal, but it definitely seems to be a pattern. First, this is bizarre, and why so? And, two... this is totally bogus... how can execute() not take place above? Perl doesn't have a habit of jumping over lines, does it?
Absolutely mystified in Madison.
Following Paul Findlay's advice, I launched my offending app with the following invocation
$DBI_TRACE=2=logs/dbi.log plackup -E production -p 5001 -s Starman -w 10 -a bin/app.pl
And, following is what stood out to me as the potential culprit in the log file
Handle is not in asynchronous mode error 2000 recorded: Handle is not in asynchronous mode !! ERROR: 2000 CLEARED by call to fetch method
(I am shooting in the dark here) I believe Dancer uses a lot of global variables. Would that be connected to this error? On occasion, I am also seeing another mysterious behavior, so mysterious that I feel I am smoking something --
One request to the web server pulls in points, and another request pulls in polys. They are called like so
http://webserver/points.json http://webserver/polys.json
They are both separate asynchronous requests, sent via separate $.ajax() jQuery calls from the browser. On occasion, and I swear I am not making this up, I see points json stream returned via the polys request. Of course, because points.json returns different data than polys.json, I get an error.
For what its worth, and this is highly unscientific, this doesn't happen if plackup is in `-E development` mode. It only happens in the `-E production -D` mode. But, I could be wrong about this as I don't have a large enough sample set to confirm this finding conclusively.
Thoughts?
A simple script like so works like a champ... no async nonsense, no errors. All 1000 requests are effortlessly returned by the same set up.
use LWP::UserAgent;
my $BBOX = "-96.09299316406248+38.96034339396338%2C+83.39279785156248+38.96034339396338%2C+-83.39279785156248+44.33256692562997%2C+96.09299316406248+44.33256692562997%2C+-96.09299316406248+38.96034339396338";
for (1 .. 1000) { open my $fh, ">>", 'foo.txt';
my $ua = LWP::UserAgent->new; $ua->agent("MyApp/0.1 ");
my $req = HTTP::Request->new(GET => "http://localhost:5001/points.json?callback=foo&BBOX=$BBOX"); my $res = $ua->request($req);
# Check the outcome of the response if ($res->is_success) { say $fh $res->content; } else { say $fh $res->status_line; }
close $fh; }
So, it seems that both MySQL and Starman are very capable of handling this. The only element missing here is Dancer, and the browser. Thoughts anyone? I am just interested in finding out the issues here, and creating a robust, workable app.
Many thanks in advance.
Puneet.
On Sunday 17 July 2011 18:18:25 Mr. Puneet Kishor wrote:
I think I may have found a reason and a (temporary) solution. Actually, I didn't find it, but a helpful person at Stackoverflow suggested that I may be creating a $dbh that might be getting shared by different Starman preforked children (see link below). I think that was the case. I am still testing it by moving the $dbh creation in the subs.
Ah, yes, that certainly sounds a plausible explanation. I'm biased of course, but might I recommend letting Dancer::Plugin::Database handle the creation & re-use of database handles for you? It's exactly what it's designed for, and it goes to lengths to ensure that handles are not shared between processes/threads, to avoid issues just like this one. -- David Precious ("bigpresh") http://www.preshweb.co.uk/ "Programming is like sex. One mistake and you have to support it for the rest of your life". (Michael Sinz)
On Friday 15 July 2011 02:55:55 Mr. Puneet Kishor wrote:
Here is the interesting thing -- if I add the -D switch to the second app as well, it fails to return the polys and the points. It fails with the error
{"error":"Warning caught during route execution: DBD::mysql::st fetchall_arrayref failed: fetch() without execute() at <path/to>/macrostrat.pm line 79.\n"}
The offending lines are
71> my $sql = qq{ 72> .. 73> 74> 75> }; 76> 77> my $sth = $dbh->prepare($sql); 78> $sth->execute(); 79> my $res = $sth->fetchall_arrayref({});
The above could be just correlation rather than causal, but it definitely seems to be a pattern. First, this is bizarre, and why so? And, two... this is totally bogus... how can execute() not take place above? Perl doesn't have a habit of jumping over lines, does it?
You haven't actually performed any error checking; either make sure RaiseError is enabled on your database handle, or check for errors, e.g.: $sth->execute() or die "Failed to execute query - " . $dbh->errstr; As for why the behaviour changed when you selected the production environment, perhaps it's down to differing settings in enviroments/development.yml and environments/production.yml ? -- David Precious ("bigpresh") http://www.preshweb.co.uk/ "Programming is like sex. One mistake and you have to support it for the rest of your life". (Michael Sinz)
-- Puneet Kishor http://punkish.org Researcher http://paleodb.org http://macrostrat.org http://carbonmodel.org Science Fellow http://creativecommons.org Charter Member http://osgeo.org On Jul 15, 2011, at 3:48 PM, David Precious <davidp@preshweb.co.uk> wrote:
On Friday 15 July 2011 02:55:55 Mr. Puneet Kishor wrote:
Here is the interesting thing -- if I add the -D switch to the second app as well, it fails to return the polys and the points. It fails with the error
{"error":"Warning caught during route execution: DBD::mysql::st fetchall_arrayref failed: fetch() without execute() at <path/to>/macrostrat.pm line 79.\n"}
The offending lines are
71> my $sql = qq{ 72> .. 73> 74> 75> }; 76> 77> my $sth = $dbh->prepare($sql); 78> $sth->execute(); 79> my $res = $sth->fetchall_arrayref({});
The above could be just correlation rather than causal, but it definitely seems to be a pattern. First, this is bizarre, and why so? And, two... this is totally bogus... how can execute() not take place above? Perl doesn't have a habit of jumping over lines, does it?
You haven't actually performed any error checking;
In a later email I did report that --
Paul Findlay's advice, I launched my offending app with the following invocation
$DBI_TRACE=2=logs/dbi.log plackup -E production -p 5001 -s Starman -w 10 -a bin/app.pl
And, following is what stood out to me as the potential culprit in the log file
Handle is not in asynchronous mode error 2000 recorded: Handle is not in asynchronous mode !! ERROR: 2000 CLEARED by call to fetch method
(I am shooting in the dark here) I believe Dancer uses a lot of global variables. Would that be connected to this error? On occasion, I am also seeing another mysterious behavior, so mysterious that I feel I am smoking something"
I posted this question on perlmonks as well, and there has been a little discussion, but nothing conclusive yet. [http://www.perlmonks.org/index.pl?node_id=914782]. I am going to try turning on the async feature in DBI and see if that make any difference.
either make sure RaiseError is enabled on your database handle, or check for errors, e.g.:
$sth->execute() or die "Failed to execute query - " . $dbh->errstr;
As for why the behaviour changed when you selected the production environment, perhaps it's down to differing settings in enviroments/development.yml and environments/production.yml ?
The development.yml and production.yml settings are identical in all meaningful ways, as far as I can tell. The only differences are the ones that dancer -a cooks up when creating a bare shell of an app... Different warning levels, warning targets, and that is about it. The only difference I can see is that with -D switch the app runs in the background, and I get no diagnostic messages. Btw, does Starman (or plackup) support logging error and accept requests like Apache does?
-- David Precious ("bigpresh") http://www.preshweb.co.uk/
"Programming is like sex. One mistake and you have to support it for the rest of your life". (Michael Sinz)
participants (3)
-
David Precious -
Mr. Puneet Kishor -
Paul Findlay