March 26, 201214 yr I have a function in a controller in cakephp which could potentially run for thousands of seconds. The function basically has a list of links and contacts several API's to get various SEO data from them. So each link can take a few seconds each. I've been trying to get a cake shell set up to do this for me but with no luck. The closest I have come is to have this bash script which runs the required shell with a parameter (30 in this case which is the id of a user on the system.) /home/linkmoni/public_html/cake/console/cake -app /home/linkmoni/public_html/app updateuserlinks 30 > update3.txt 2> update3.err & then call this script from within my controller $result = exec("sh update_links.sh > update2.txt 2> update2.txt"); Now, the bash script works if I ssh into my server and run it directly from there. All the links update correctly and everything is fine. When running from php exec there seems to be a problem. As far as I can tell it's to do with a requirement for a user to be logged in. After running the above code the only text is found in update3.txt Status: 302 Moved Temporarily X-Powered-By: PHP/5.2.17 P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM" Location: http://linkmoni.com/~linkmoni/links Content-type: text/html Before I got to this point I tried messing around with wget and session cookies which worked to some extent but required a particular users login credentials. This worked in that it bypassed the systems login, but I couldn't get it to access any of the models data. Does anyone know how I can get this to work? Basically all I want to do is run this long function in the background, whilst having access to the cakephp models. Thanks everyone! Edited March 26, 201214 yr by kirky_D
March 27, 201214 yr Author I've added this to the relevant controller: function beforeFilter(){ parent::beforeFilter(); $this->Auth->allow('updatealluserlinksinternal'); } Which I believe will fix the issue. But I've just noticed a really strange problem. The exec call seems to call the script hundreds of times. I've added the following to my bash script: echo "Bash running" >> bash.txt after running the function once, I get thousands of "Bash running" entries in bash.txt. Now I imagine some of you will probably think there is a loop somewhere, and I'm 99.999% certain there isn't, but I'll try and add as much of the process as possible. First of all in the web browser I am looking at the 'Links' view. This displays all links for a given user. There is a link on this page called 'Update all Links'. The href for this points to /~linkmoni/links/updateAllUserLinks which is a function in the 'LinksController' this function is exactly this: function updateAllUserLinks(){ //call external script which allows us to run the update in the background $result = exec("sh update_links.sh > update2.txt 2> update2.err"); Debugger::log($result); $this->Session->setFlash(__('The links have been set to update. Their associated data will be refreshed within the next 30 minutes.', true)); $this->redirect(array('action' => 'index')); } This is the 'update_links.sh' script which is located in the webroot folder: #!/bin/bash echo "Bash running" >> bash.txt /home/linkmoni/public_html/cake/console/cake -app /home/linkmoni/public_html/app updateuserlinks 30 > update3.txt 2> update3.err This calls a cake shell called updateuserlinks.php which resides in /vendors/shells (not /app/vendors/shells). Here are the contents: <?php class UpdateUserLinksShell extends Shell { var $uses = array('Link', 'User', 'Website'); function main() { Debugger::log("Entered Shell"); $id = $this->args[0]; $this->requestAction("/links/updatealluserlinksinternal/$id"); } } ?> This calls a function within the 'Links' controller called updateAllUserLinksInternal($id) function updateAllUserLinksInternal($id){ $this->Link->recursive = 0; //gets all the website ids for the current user $websites = $this->Website->find('all', array('conditions' => array('Website.user_id' => $id))); $websiteids = array(); $websiteUrls = array(); $i = 0; foreach($websites as $website){ $websiteids[$i] = $website['Website']['id']; $i++; } $links = $this->Link->find('all', array('conditions' => array('Link.website_id' => $websiteids))); foreach($links as $link){ $this->updateLink($link['Link']['id'], false); sleep(5); // give 5 seconds to update each link to ensure no mySQL limit reached errors } } And that's it. Like I said before this works when calling the script from the command line, but not from php's exec function. So I think the problem might be there, but I really can't figure it out. Thanks all! EDIT It appears that the cake shell is running forever. This command is listed in my process maanger: php -q /home/linkmoni/public_html/cake/console/cake.php -working /home/linkmoni/public_html/app/webroot -app /home/linkmoni/public_html/app updateuserlinks 30 I also have over 25,000 "Bash running" entries in bash.txt. What I find strange is the above command doesn't call the bash script, it's actually the other way round so you would expect lots of entries in the process manager if that command was called multiple times Edited March 27, 201214 yr by kirky_D
Create an account or sign in to comment