• Resolved chathu020

    (@chathu020)


    I have an infinity running process like syncing data remotely in every 2minutes. So I have added a task and that task reads the data table and process each row and call remote apis for updating. I have tested with adding 1000 rows and it hung up at about 53.
    with max execution time out.

    Then the next run also not working and whole task is hung out.
    Here are my configurations.

Viewing 15 replies - 1 through 15 (of 33 total)
  • Plugin Author miunosoft

    (@miunosoft)

    Hi,

    Hmm, I could not reproduce the problem on my end. Can you tell me the steps to reproduce it. If I could reproduce it, most likely it will be fixed.

    Thank you.

    Thread Starter chathu020

    (@chathu020)

    hi,
    It is on my local environment and it is like within one task there it is getting 1000 rows from database and for each row (row is like a separate event now) it reads google tasks of the user and according to that each task it updates some data. So it is like 1000users are doing this in one task.
    Alternatively, I am thinking on adding 1000tasks for each user or more. My problem is performace. Do you have tested this with like 1000-2000 tasks added and each tasks is calling within 2minutes time frame?
    Will it hung up with this?

    Plugin Author miunosoft

    (@miunosoft)

    Hi,

    1000 tasks, that’s a lot. I haven’t tested such a number of tasks running simultaneously but have you tried increasing the maximum execution time of PHP? It might help solving the problem.

    Thread Starter chathu020

    (@chathu020)

    But inside one task is it running synchronously right?
    but when we call 1000tasks they are asynchronous and make threads for each, right?

    Plugin Author miunosoft

    (@miunosoft)

    Then a task is called, a routine is spawned and code defined in a routine runs synchronously. If there are multiple tasks and they are called at the same time, their routines will run asynchronously.

    Thread Starter chathu020

    (@chathu020)

    ok so adding multiple tasks is fine I think, can you please guide me how to add dynamic tasks with my plugin coding. If so it will be a great help.
    thanks in advance.

    Plugin Author miunosoft

    (@miunosoft)

    It’s not recommended to create 1000 tasks dynamically as task are persistent. Instead you can create treads that belongs to a routine. A routine belongs to a task.

    Task (persistent) -> Routine (called from a task) -> Thread (called from a routine)

    In order to create a thread, you need to create your custom action class and in the doAction() method of the class, you need to call TaskScheduler_ThreadUtility::derive( $iRoutineID, $aThreadOptions );

    The first parameter is the routine ID (integer) and the second parameter is an array of thread options.

    Look at the TaskScheduler_Action_PHPScript class and how it calls threads.

    Thread Starter chathu020

    (@chathu020)

    in that case is it possible to pass wordpress class funtion to $aThreadOptions?
    what I found it is passing a php script.
    Can you give me an example to pass php function from custom class?

    Plugin Author miunosoft

    (@miunosoft)

    The TaskScheduler_Action_PHPScript class is pretty much an example.

    1. Decide your action name. e.g. task_scheduler_action_remote_database_updater.
    2. Create an action class extending the TaskScheduler_Action_Base class.
    3. Create a thread class extending the TaskScheduler_Action_Base class.
    4. In the doAction() method of the action class defined in the above step 2, create a thread by calling TaskScheduler_ThreadUtility::derive().
    5. In the doAction() method of the thread class defined in the above step 3, do actual database updates.
    6. In the construct() method of the action class, instantiate the thread class passing the action name, made up in the step 1.

    To pass a function name to a thread, set a function name in the $_aThreadOptions array like $_aThreadOptions[ 'func_name' ] then in the doAction() of the thread class, you get options with $_aThreadOptions = $oRoutine->getMeta(); the object $oRoutine is passed with the second parameter of the doAction() method. Then you can call your function with call_user_func_array();

    I would do something like this.

    
    class YourTaskAction extends TaskScheduler_Action_Base {
    
        public function construct() {         
            new YourThreadActionClass( 'task_scheduler_action_remote_database_updater' );
        }
        public function getLabel( $sLabel ) {
            return 'My Task Action Name';
        }    
        public function getDescription( $sDescription ) {
            return 'Here is my description.';
        }
        
        public function doAction( $isExitCode, $oRoutine ) {
            
            $_aTaskMeta = $oRoutine->getMeta();
            if ( ! isset( $_aTaskMeta[ $this->sSlug ] ) ) {
                return 0;    // failed
            }
            
            // Handle each database row per thread
            $_aRows    = $this->___getRows();
            $_iThreads = 0;
            $_iCount   = 0;
            foreach( $_aRows as $_aRow ) {
                
                $_iCount++;
                $_aThreadOptions = array(
                
                    // Required
                    'routine_action'        => 'task_scheduler_action_remote_database_updater',
                    'post_title'            => sprintf( __( 'Thread %1$s of %2$s', 'task-scheduler' ), $_iCount + 1, $oRoutine->post_title ),
                    'parent_routine_log_id' => $oRoutine->log_id,        // the log_id key is set when a routine starts
                                               
                    // internal options        
                    '_next_run_time'        => microtime( true ),            
                    
                    // Routine specific options
                    'func_name'             => 'my_func_name',
                    'func_params'           => $_aRow,
                    
                );
                
                $_iThreadTaskID = TaskScheduler_ThreadUtility::derive( $oRoutine->ID, $_aThreadOptions );
                $_iThreads      = $_iThreadTaskID ? ++$_iThreads : $_iThreads;            
    
            }
            
            // Check actions in the background.
            if ( $_iThreads ) {
                do_action( 'task_scheduler_action_check_scheduled_actions' );
            }
            
            return null;    // exit code: do not log; it will be, when the threads finish.
            
        }
    
        /**
         * Retrieve database rows.
         * @return array
         */
        private function ___getRows() {
            return array();    
        }
        
    }
    
    class YourThreadActionClass extends TaskScheduler_Action_Base {
        
        public function getLabel( $sLabel ) {
            return 'Remote Database Updater';
        }
        /**
         * Do you stuff
         */
        public function doAction( $isExitCode, $oThread ) {
            $_aThreadMeta = $oThread->getMeta();
            return call_user_func_array( $_aThreadMeta[ 'func_name' ], $_aThreadMeta[ 'func_params' ] );
        }   
        
    }
    

    In the ___getRows() function, it is returning an array but in your actual code, you are supposed to retrieve database rows. Modify the code as you need.

    Thread Starter chathu020

    (@chathu020)

    ok Thanks in advance, I will try this and update you

    Plugin Author miunosoft

    (@miunosoft)

    In my previous reply, it is assumed that you know how to create a custom action module. In case you are not aware of it, see this thread. It talks about an example action module that you can modify, which should be simpler for you.

    Thread Starter chathu020

    (@chathu020)

    ok I used ‘My Task Action Name’ as action from UI but it seems not working. Why is YourThreadActionClass is extending TaskScheduler_Action_Base ? do I suppose to use ‘My Task Action Name’ or ‘Remote Database Updater’;

    Plugin Author miunosoft

    (@miunosoft)

    Why is YourThreadActionClass is extending TaskScheduler_Action_Base ?

    It is how it is designed.

    do I suppose to use ‘My Task Action Name’ or ‘Remote Database Updater’;

    Name whatever you like.

    So have you created a custom action module?

    Thread Starter chathu020

    (@chathu020)

    I found that it fails at

    if (!isset($_aTaskMeta[$this->sSlug])) {
                return 0;    // failed
           }

    actually $_aTaskMeta['routine_action'] = $this->sSlug, Am I right?

    • This reply was modified 4 years, 3 months ago by chathu020.
    Plugin Author miunosoft

    (@miunosoft)

    Ah, indeed that key is only set when the action has its UI. Sorry about that.

    The array value of the key ‘routine_action’ should be the same as $this->sSlug property value.

    By the way, when your site debug mode is turned on (define( WP_DEBUG, true)), you can use TaskScheduler_Debug::log( $oRoutine->getMeta() ); to check the passed arguments.

Viewing 15 replies - 1 through 15 (of 33 total)
  • The topic ‘Task hungs up’ is closed to new replies.