Yii Framework Forum: runaction - Background actions - Yii Framework Forum

Jump to content

  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

runaction - Background actions Rate Topic: -----

#1 User is offline   teeaich 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 1
  • Joined: 29-May 11

Posted 29 May 2011 - 08:28 AM

Hi,

can anybody explain me the functionality of the background actions of the extension 'runactions' in detail?

I havent got a clue to implement such a function generally.

In the documentation i could find just the following code which doesnt help me to understand whats going on.

public function actionTimeConsumingProcess()
    {
        if (ERunActions::runBackground())
        {
           //do all the stuff that should work in background
           //mail->send() ....
        }
        else
        {
            //this code will be executed immediately
            //echo 'Time-consuming process has been started'
            //user->setFlash ...render ... redirect,
        }
    }


Where should i put this function? Within my controller? In the next step i thought i simply call the function normally. But obviously i was wrong:-) nothing happend and only the else part was executed. So in my next attempt i call my function with the help of:

ERunActions::runAction('bookmark/TimeConsumingProcess',$params=array(),$ignoreFilters=true,$ignoreBeforeAfterAction=true,$logOutput=false,$silent=false);


but...nothing happend. Although the false part has been executed again.
so, i gave this method a chance

ERunActions::touchUrlExt($url,$postData=null,$contentType=null,$httpClientConfig=array());


which should triggered my background job code in the if part. But in this case nothing happened at all. Even the else part has been omitted.

So, as you guess, my proramming skills are really far away from average:-)

Can anybody help me to explain me the basic functionality of this extension when i'm going to execute code in the background.

sorry for my bad english. thanks for any advice.

greets

Thorsten
0

#2 User is offline   day day up 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 10
  • Joined: 27-December 10

Posted 01 June 2011 - 03:33 AM

Sorry for my broken english ,but i have to say that i have the same questiones.

I tested ERunActions::touchUrl(),but nothing is happend.

Then i tested RunActionsController::actionTouch() and with a corn.php return an array ,it works,but used ERunActions::TYPE_ACTION
0

#3 User is offline   Joblo 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 682
  • Joined: 12-September 10
  • Location:Austria

Posted 01 June 2011 - 07:27 PM

You can use ERunActions::runBackground() - as described - in a controller action.
Try this for testing - slightly modified comparing to documentation:

public function actionIndex()
    {
        if (ERunActions::runBackground())
        {
           Yii::log('Starting background task...');

           //... time-consuming code here
           
           //Inform the user if 'hasFlash' is implemented in all views
           //Yii::app()->user->setFlash('runbackground','Process finished');

           Yii::log('Background task executed');
           Yii::app()->end(); 
        }
       
           //the stuff you normally would do 
           //for example:
           $this->render('index');
    
    }


Check the runtime/application.log to see if the background code was executed.

Check the source to understand, what happens when ERunActions::runBackground

When the user calls the controller actionIndex,
the same url will be 'touched' internally to execute the background part.

When using ERunActions::touchUrl('http://www.yiiframework.com') a request will be sent to this webserver, nothing more happens, you can't see anything, because touchUrl doesn't care about what this host is doing to handle the request, doesn't care about the data the webserver will send after the request.

The only thing that happend is, that the 'touched' host will start working, will do something, but your code is not interested in what really happens.

So this can be useful for transfering data between webservers. When a url is 'touched' the webserver can post data to another (or the requesting) host (using EHttpClient at the other host):

- When you call the action url in your browser you maybe have to wait minutes until the work ist done: collecting/preparing data, send ...

- By using 'touchUrl' the client will not wait until the process is finished.

And it's useful for ERunActions::runBackground() to start asynchronous 'background' tasks at the own webserver.
1

#4 User is offline   day day up 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 10
  • Joined: 27-December 10

Posted 01 June 2011 - 08:34 PM

Thank you for your help. It's real worked.

There are still a question:

When i used touchUrl() in another action ,nothing has happened but waitting for the respond.

Because of the timeout setting in the request()?

   //in action index,maybe i should't do this 
   ERunActions::touchUrl($this->createUrl('site/timeConsumingProcess'));


Where and when i could use this method(ERunActions::touchUrl) ?
0

#5 User is offline   Joblo 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 682
  • Joined: 12-September 10
  • Location:Austria

Posted 02 June 2011 - 08:56 AM

You have to use createAbsoluteUrl() instead of createUrl(), because touchUrl only works with full specified urls.

Note: I have updated the extension to version 1.1
0

#6 User is offline   day day up 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 10
  • Joined: 27-December 10

Posted 02 June 2011 - 09:03 AM

Thanks a lot! It's indeed a useful extension. :lol:
0

#7 User is offline   John J 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 11
  • Joined: 05-July 11
  • Location:Golden Grove, South Australia

Posted 13 September 2011 - 12:07 AM

Will this run on Windows under a WAMP server?
0

#8 User is offline   Joblo 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 682
  • Joined: 12-September 10
  • Location:Austria

Posted 13 September 2011 - 01:20 AM

Yes, it will.
It's developed under Win 7, Apache 2.2, PHP 5.3.
0

#9 User is offline   John J 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 11
  • Joined: 05-July 11
  • Location:Golden Grove, South Australia

Posted 14 September 2011 - 09:08 PM

I just could not get this working. My problem is effectively the same as the OP in this thread, where the action called with runBackground only ever returned false, and never ran the code that should work in the background.

This was the case with WAMP Server on WinXP, Apache 2.n, and PHP 5.n.

I also uploaded to a Debian Linux server, and still no dice. The runBackground function was called, returned false, and never retouched the action.

I traced through the code and everything executed without error. The client->request function returned via the successful path, but still the background thread never executed.

After many hours I gave up and used the php exec function to run a bash script in the background, that called the PHP script to do the processing.
0

#10 User is offline   Joblo 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 682
  • Joined: 12-September 10
  • Location:Austria

Posted 18 September 2011 - 02:39 AM

See my comment at runactions
0

#11 User is offline   Tibor Katelbach 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 81
  • Joined: 11-April 11
  • Location:Reunion Island

Posted 09 January 2012 - 11:09 AM

Hi Joblo
I'm really interested in your extension, it describes precisly what I need
but I run into the same thing as the others
here is my controller , any idea why ERunActions::runBackground() is always false ?
public function actionTest (){
        if (ERunActions::runBackground())
        {
           Yii::log('Starting background task...', CLogger::LEVEL_WARNING, 'CronController');
           //ERunActions::touchUrl($this->createAbsoluteUrl('/cron/talk'),$postData=null,$contentType=null);
            Yii::app()->user->setFlash('runbackground','Process finished');
           Yii::log('Background task executed', CLogger::LEVEL_WARNING, 'CronController');
           Yii::app()->end(); 
        }
       
          echo "<br/>do this now";
    }


I've tried many different possibilities from your doc , but I must admit
It's a bit missleading to have documentation in different locations
is the main documentation wrong ?
That's what I seem to understand from the comments ?
but can't get it to work :(
0

#12 User is offline   Joblo 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 682
  • Joined: 12-September 10
  • Location:Austria

Posted 10 January 2012 - 03:04 AM

If you debug the code above, ERunActions::runBackground() will always return false.
This is ok, because the code below
echo "<br/>do this now";
should be executed immediatly.

But what happens, is that the httpclient does a second call to actionTest by ERunActions::touchUrl. If the url is 'touched' the method ERunActions::runBackground() returns true and the code inside the runBackground block will be executed.
But this happens in another 'thread' you are not debugging.

But what's the problem?
If you can't find a log item ensure that you have enabled the level 'CronController' in you log config.

Try with a simple code first and check if there is a log item.

public function actionTest ()
{
        Yii::import('ext.runactions.components.ERunActions');

        if (ERunActions::runBackground())
        {
           Yii::log('running in Background',CLogger::LEVEL_ERROR);
           Yii::app()->end(); 
        }
       
        echo "<br/>do this now";
}


or this

public function actionTest ()
{
        Yii::import('ext.runactions.components.ERunActions');

        if (ERunActions::runBackground())
        {
           Yii::log('running in Background',CLogger::LEVEL_ERROR);
        }
        else
          echo "<br/>do this now";
}

0

#13 User is offline   vgfitzger 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 1
  • Joined: 12-January 12
  • Location:Los Angeles

Posted 14 March 2012 - 03:27 PM

View PostJoblo, on 10 January 2012 - 03:04 AM, said:

If you debug the code above, ERunActions::runBackground() will always return false.
This is ok, because the code below
echo "<br/>do this now";
should be executed immediatly.

But what happens, is that the httpclient does a second call to actionTest by ERunActions::touchUrl. If the url is 'touched' the method ERunActions::runBackground() returns true and the code inside the runBackground block will be executed.
But this happens in another 'thread' you are not debugging.

But what's the problem?
If you can't find a log item ensure that you have enabled the level 'CronController' in you log config.

Try with a simple code first and check if there is a log item.

public function actionTest ()
{
        Yii::import('ext.runactions.components.ERunActions');

        if (ERunActions::runBackground())
        {
           Yii::log('running in Background',CLogger::LEVEL_ERROR);
           Yii::app()->end(); 
        }
       
        echo "<br/>do this now";
}


or this

public function actionTest ()
{
        Yii::import('ext.runactions.components.ERunActions');

        if (ERunActions::runBackground())
        {
           Yii::log('running in Background',CLogger::LEVEL_ERROR);
        }
        else
          echo "<br/>do this now";
}


Is it possible that the controller's filter function isn't allowing runBackground() to touch the current controller's action without having that second thread log in?

If so, is it possible to pass runBackground() the Session info that Yii is looking for or is it impossible for runbackground() to work on actions that are restricted to authenticated users?
0

#14 User is offline   webservice 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 13
  • Joined: 15-December 10

Posted 02 May 2012 - 01:51 AM

Hello, I try to send some emails inside the controllers and for a reason it doesn't work because of the GET POST vars. In general when we want to send emails then this process some times takes time so with background action works perfect, the issue is what we can do when we want to do it inside a controller.
0

#15 User is offline   Joblo 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 682
  • Joined: 12-September 10
  • Location:Austria

Posted 03 May 2012 - 07:23 AM

runactions should submit GET/POST vars too.

Take a look at this comment , maybe that's the problem.

Did you try to use it with the ehttpclient extension?
0

#16 User is offline   itsmekhanh 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 1
  • Joined: 13-August 12

Posted 13 August 2012 - 08:25 PM

Hi Joblo, I tried adding this test action to my controller:

public function actionTest ()
{
        Yii::import('ext.runactions.components.ERunActions');

        if (ERunActions::runBackground())
        {
           Yii::log('running in Background',CLogger::LEVEL_ERROR);
        }
        else
          echo "<br/>do this now";
}


but the runBackground block is still not being executed since I can't find the entry in the application.log file. Is there anything that I'm missing? I have version 1.1 in my extensions folder. Much thanks! This extension will be very useful!!
0

#17 User is offline   Fercho 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 10-February 12

Posted 22 August 2012 - 06:13 PM

I tried this and it doesn't save anything in database

    public function actionTest(){
        if (ERunActions::runBackground())
        {
            Yii::log('Running actionTest in Background',CLogger::LEVEL_ERROR);
            Yii::app()->db->createCommand()->insert('test', array(
                    'temp' => 'NULL',
            ));
            Yii::app()->end();
        }
        
        echo "Do this now";
        
    }


I also tried and i get no data in db

ERunActions::runAction('mycontroller/test');
public function actionTest(){
            Yii::app()->db->createCommand()->insert('test', array(
                    'temp' => 'NULL',
            ));
    }


I dont see any issue or problem in my code, what i'm missing?
0

#18 User is offline   jaimes 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 09-June 12

Posted 19 December 2012 - 10:50 AM

Hi all, i am just getting crazy trying to make this to work. it would only work if I uses the last value in $notif but what i need is to get from db the boolean make it through the if and finally send the message. It just doen't go through the "if" if value is true. Does anyone know how to make this to work? Thanks a lot..
   
$notif=(int)$userdb->notif; // notif is a boolean but it doesnt work
            $notif=(bool)$userdb->notif; // notif is a boolean but it doesnt work
           $notif=(boolean)$userdb->notif; // notif is a boolean but it doesnt work

Yii::import('ext.runactions.components.ERunActions');
if(ERunActions::runBackground()){
$notif=(int)$userdb->notif; // notif is a boolean but it doesnt work
$notif=(bool)$userdb->notif; // notif is a boolean but it doesnt work
$notif=(boolean)$userdb->notif; // notif is a boolean but it doesnt work
$notif=true; // this is the only way it would work, it would go through the following if, but what i need is other previous options. Also tested ouside
if($notif){
// it just doesnt executes only if i assign $notif=true directly....
$deviceToken=7A2xxxxxxxxxxxxxxxxxxxxxxxx3B'xxxxxxxxxxxx;
$message='New User Bla Bla Bla';
$badge=1;
Yii::app()->getModule('myapns')->startConnection();
Yii::app()->getModule('myapns')->createMessage($deviceToken,$message,$badge);
Yii::app()->getModule('myapns')->closeConnection();
}
}
0

#19 User is offline   Twisted Whisper 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 9
  • Joined: 21-June 13

Posted 21 June 2013 - 05:14 AM

For those of you who couldn't get runactions to work, perhaps I'm able to shed some light (I learnt it the hard way though). As Joblo has pointed out in his #12 post, ERunActions::runBackground() will always return false. Only after that, ERunActionsHttpClient will automatically do a second call to the same url (Controller Function) where the ERunActions::runBackground() block resides using ERunActions::touchUrl. This time, ERunActions::runBackground() will return true and executes the intended codes in a separate 'thread'.

However, the url is 'touched' by ERunActionsHttpClient under an Unauthenticated User role. So, if the url in question can only be accessed by Authenticated Users, ERunActionsHttpClient will be redirected to the login screen. The intended codes didn't execute because the call was being redirected to the login screen on a different 'thread' which you can't see and led you to think that the entire thing is broken at best.

In order for it to work, ERunActionsHttpClient will have to be passed the cookie which holds the session ID (assuming you're using cookie to preserve session). In ERunActions.php, for the function touchUrl, replace the last line

$client->request($host,$port,$uri,$verb,$urlParams,$postData,$contentType);


with

$client->request($host,$port,$uri,$verb,$urlParams,$postData,$contentType,array('PHPSESSID'=>$_COOKIE['PHPSESSID']));


Replace 'PHPSESSID' with whatever the session cookie is named. The above changes will perhaps solve your problem. You can modify the codes above so that it is more reusable by making the cookie into a parameter.

Anyway, I found out even if it works, the background 'thread' that is running the time consuming codes will block off all incoming request until it had finished executing. You can try this by doing a
sleep(60)
in the background 'thread' to simulate a long running process (like generating a report). Although, the foreground 'thread' will be immediately returned to your control, try visiting other pages in the same website. You will find that it will hang there and not responding until the background 'thread' has finished processing.
0

#20 User is offline   Kailas P. Bedarkar 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 15
  • Joined: 14-December 13

Posted 25 March 2014 - 02:12 AM

How can I call these by ajax call?
0

Share this topic:


  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users