...
Here is the matrix of what's currently supported by In-Portal:
Interactive | Non-Interactive | |
---|---|---|
User Triggered |
|
|
System Triggered |
|
|
Thoughts:
- interactive tasks are blocking UI and therefore user can't do something else in Admin Console while they are running
- user don't create about real-time status update of interactive tasks in most (but not all) cases, but just wants to know when they're completed
- scheduled tasks (system triggered non-interactive tasks):
- provide limited insight about task execution status
- only retain last task execution status
- e-mail queue:
- successfully executed tasks are removed from queue (the "E-mail Logs" section sort of compensates for that currently)
- no error information is stored within task
...
- create "
ITaskHandler
" interface with "handleTaskRun(kDBItem $task_run)
" method - 0.5h - create "
TaskQueue
" database table (unit name "task-queue
") with following columns: - 1hId
TaskHandlerClass
- FQCN of PHP class, which is responsible for processing this task queue record (must implement "ITaskHandler
" interface)TaskData
- JSON-encoded data, that is needed for task execution (e.g. e-mail recipient, IDs of records to be processed)ScheduledOn
- when task needs to be processed (set at queuing time)QueuedOn
- when task was queuedQueuedById
- who queued the taskLastStatus
- status from last attempt of this queue record processing (same options as for "TaskRuns.Status
" field)MaxRetries
- if task fails specified number of times (5 by default), then don't retry itTaskRunsFailed
- number failed task runs (number is reset, when task execution was successful)
- create "
TaskRuns
" database table (unit name: "task-run
") with following columns: - 1hId
TaskQueueId
- ID of record from "TaskQueue
" table, that is responsible for creation this runStartedOn
- when task run was started; NULL set to moment, when status changes from "scheduled
" to "processing
"PercentsCompleted
- "0
" by default, but will be updated as task is being processedFinishedOn
- when task was finished executing (regardless of status)Results
- JSON-encoded results in any format, that be later displayed in human-readable formStatus
- same statuses as for "TaskQueue.LastStatus" column- "
scheduled
" - initially, when record is created; - "
running
" - when somebody is processing the record; - "
success
" - when execution finished without errors; - "
error
" - when known error happened during processing; - "
timeout
" - when associated task runner died unexpectedly
- "
StandardOutput
- what was written to "stdout" stream during this task runErrorOutput
- what was written to "stderr" stream during this task runErrorCode
- non-empty when known error happenedErrorMessage
- non-empty when known error happenedTaskRunnerId
- NULL by default; ID of task runner that processing/processed given task run
- create "
TaskRunners
" database table (unit name: "task-runner
") with following columns: - 1hId
ProcessId
- the PID of process, that started/created task runnerStartedOn
- when process was startedFinishedOn
- when process was finished; NULL initiallyStatus
- status of task runner:- "
running
" - default; means task runner is running - "
success
" - set, when task runner decides to kill itself - "
timeout
" - set by overseer when task runner in "running
" status and associated process isn't running
- "
- in "
task-run:OnAfterItemUpdate
" event will: - 0.5h- load "
task-queue
" object associated with updated task run - get all "
task-run
" records for that "task-queue
" (via sql); then sort them from recent to old (via php) - set following fields on "task-queue" object:
- "
LastStatus
" to "Status" of most recent "task-run" - "
TaskRunsFailed
" to count of "task-run" records in "error" and "timeout" statuses (if last run is failed) - "
TaskRunsFailed
" to "0" (if last run was successful)
- "
- load "
- in "
task-runner::OnBeforeItemCreate
" event set "ProcessId
" to PID of current process - 0.1h - in "
task-runner:OnAfterItemUpdate
" event, when "Status
" changes from "running
" to "timeout
" set all "task-run
" status, that are processed by this task runner from "running
" to "timeout
" as well - 0.3h - the "
task-run
" would be sub-item of "task-queue
" unit - 0.1h
Part 2 (adding tasks & runs) -
...
5h (sum)
- create "
TaskQueue
" class (not item of "task-queue
" unit) - 0.1h - add protected "
TaskQueue::createTaskHandler($class_name)
" method, that will: - 0.5h- create instance of given class or throw an exception when failed
- if created object doesn't implement "
ITaskHandler
" interface, then throw an exception - return the object
- add public "
TaskQueue::addTask($task_handler_class, array $task_data, $scheduled_on, $max_retries = null)
" method, that will: - 0.4h- call "
TaskQueue::createTaskHandler
" method to verify, that class given in "$task_handler_class
" parameter is valid - consider "
$max_retries
" as "5
" when not given - create new db record using provided data using "
task-queue
" object
- call "
- add public "
TaskQueue::refreshTaskRunnersStatus()
" method that will: - 0.5h- get all "
task-runner
" in "running
" status - if associated process isn't running anymore, then set "
task-runner
" status from "running
" to "timeout
" (the "task-runner::OnAfterItemUpdate
" would update connected task runs)
- get all "
- add protected "
TaskQueue::createTaskRun(kDBItem $task_queue)
" method, that will: - 0.5h- will create new task run (and return it's ID) for given queue record, when all of following rules aren't violated:
- only 1 (or less) running "
task-run
" can exist for one "task-queue
" record - "
TaskRunsFailed
" must be smaller, then "MaxRetries
" on associated "task-queue
" record
- only 1 (or less) running "
- return "
null
" otherwise
- will create new task run (and return it's ID) for given queue record, when all of following rules aren't violated:
- add protected "
TaskQueue::createMissingTaskRuns()
" method, that will: - 0.5h- get all records from "
TaskQueue
" table, for which task runs can be created:ScheduledOn
<NOW()
LastStatus
is not "running
"TaskRunsFailed
must be smaller, thenMaxRetries
- call the "
TaskQueue::createTaskRun
" method on each of them (method can return "NULL" in some cases, but that's ok)
- get all records from "
- add protected "
TaskQueue::getTaskRunnerCount()
" method, that will return number of "task-runner
" in "running
" status - 0.3h - add protected "
TaskQueue::getMissingTaskRunnerCount()
" method, that will: - 0.2h- get value of "
TaskRunnerLimit
" system setting - call "
TaskQueue::getTaskRunnerCount
" method - return difference or 0, when difference is negative
- get value of "
- add public "
TaskQueue::runStandalone()
", that will: - 0.5h- call "
TaskQueue::getTaskRunner
" method - if object is returned call "
->process()
" method on it
- call "
- add public "
TaskQueue::createMissingTaskRunners()
" method, that will: - 1h0.5h- if in CLI:
- call "
TaskQueue::getMissingTaskRunnerCount
" method - if it returned "0" do nothing
- execute command (see last plan) X number of times in background processes (X - number returned above)
- call "
- if not in CLI:
- call "
TaskQueue::getTaskRunner
" methodif object is returned call "->process()
runStandalone
" method on it
- call "
- if in CLI:
- add public "
TaskQueue::processQueue()
" method, that will: - 0.4h- call "
TaskQueue::
" methodrefreshTaskRunnersStatus
- call "
TaskQueue::
createMissingTaskRunnerscreateMissingTaskRuns
" method (might not be the best idea if user wants to manage task runners externally)
- call "
- create "
task-queue:OnProcess
" event, that: - 0.1h- would be called as Scheduled Task on a regular basis (e.g. each 5 minutes)
- would call "
TaskQueue::
createMissingTaskRunsprocessQueue
" method
- create "
task-queue:
OnProcessOnCreateTaskRunners
" event, that: - 0.1h3h- would be called as Scheduled Task on a regular basis (e.g. each each 5 minutes) would call - can be disabled if needed
- will call "
TaskQueue::createMissingTaskRunners
" method
- create "
task-queue:OnDebug
" event, that will call "TaskQueue::
processQueuerunStandalone
" method - 0.2h
Part 3 (running runs) - 4.5h (sum)
...
configure either of following, but not as scheduled task, because it will block all other scheduled tasks:
command:
/usr/bin/env php /path/to/in-portal/tools/run_event.php task-runner:OnProcess password_here
setup "
upstart
" or "supervisord
" or any other tool to ensure presence of X processes powered by above commandadd X records to "crontab" file powered by above command
task can be created through calling "
TaskQueue::addTask
" method by whoever needs it, e.g.:- user presses a button
- scheduled task decides to offload some work
- etc.
Quote: 16.5h17h*1.4=23h24h
Related Discussions
...