Task hungs up
-
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.
-
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.
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?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.
But inside one task is it running synchronously right?
but when we call 1000tasks they are asynchronous and make threads for each, right?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.
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.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 callTaskScheduler_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.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?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 theTaskScheduler_Action_Base
class.
3. Create a thread class extending theTaskScheduler_Action_Base
class.
4. In thedoAction()
method of the action class defined in the above step 2, create a thread by callingTaskScheduler_ThreadUtility::derive()
.
5. In thedoAction()
method of the thread class defined in the above step 3, do actual database updates.
6. In theconstruct()
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 thedoAction()
of the thread class, you get options with$_aThreadOptions = $oRoutine->getMeta();
the object$oRoutine
is passed with the second parameter of thedoAction()
method. Then you can call your function withcall_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.ok Thanks in advance, I will try this and update you
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.
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’;
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?
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.
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 useTaskScheduler_Debug::log( $oRoutine->getMeta() );
to check the passed arguments.
- The topic ‘Task hungs up’ is closed to new replies.