Class waLongActionController
This controller helps to implement potentially long operations when it's impossible to avoid max execution time limit.
Each operation is identified by processId. It is possible to run several processes with different ids at the same time.
Only one instance of (descendant of) this class with given id can be a Runner at given time. Runner is an instance that performs actual work. Runner works until he's done or until he dies exceeding max execution time. Browser must request page again from time to time if old connection gets closed to resume the process.
While Runner is alive, all other possible instances will automatically become Messengers. Messenger don't do real work but can access (and give to user) some information about Runner's status.
It is possible to keep data that is guaranteed not to became corrupt regardless of when (or if) script fails. $this->data is a persistent array and $this->fd is a file descriptor with this guarantee. Only Runner has write access to this persistent data. All data in $this->data must be serializable.
For all methods of this class that are called inside a transaction:
- If a script fails inside a transaction then all changes to $this->data and $this->fd file get reverted and are not visible inside subsequent transactions.
- If transaction completes successfully then all changes to $this->data and $this->fd are visible to subsequent transactions.
Execution time for every function that runs inside a transaction must be reasonably small for this class to be able to keep it's guarantees. Reasonably small = no more than 10% of max execution time for each transaction.
Controller's entry point for this class expects a 'processId' get or post parameter. It then becomes available as $this->processId. If id is not given in request, a new process is started and $this->info() is responsible for returning id to user for subsequent operations. $this->newProcess indicates whether this Runner created the process (true) or not (false).
$this->finish() gets called when $this->isDone() return true. If $this->finish() return true, then process removes all its files and cannot be accessed again. Otherwise another instance can be called for this process to access the same result data and file.
Besides $this->fd and $this->data, $this->max_exec_time is also available for reading. It contains max execution time for this script (false if unknown).
- waController
-
waLongActionController
Package: wa-system\controller
Copyright: 2011 Webasyst LLC
Author: Webasyst LLC
Located at wa-system/controller/waLongActionController.class.php
protected
boolean
|
|
abstract protected
|
|
abstract protected
boolean
|
|
abstract protected
boolean
|
|
abstract protected
boolean
|
|
protected
|
|
protected
|
|
public
|
|
private
|
|
private
|
#
_initDataStructures( )
Creates private files and $this->... data structures for new process. Initializes $this->_processId, $this->_data, $this->_fd, $this->_runner = true Called once when a process is created. |
private
string
|
#
_obtainLock( )
Checks if there's a Runner for $this->processId. If there is one then initializes $this->_data, $this->_runner = false If there are no Runner then initializes $this->_data, $this->_fd, $this->_runner = true\ |
private
Array|boolean
|
|
private
String
|
|
private
|
|
private
|
|
protected
|
|
private
|
|
private
boolean
|
|
public
&
|
|
public
|
|
private
|
|
private
|
|
public static
|
|
private
|
__call(),
appSettings(),
configPath(),
getApp(),
getAppId(),
getConfig(),
getPluginRoot(),
getRequest(),
getResponse(),
getRights(),
getStorage(),
getUser(),
getUserId(),
log(),
logAction(),
preExecute(),
redirect(),
run(),
storage()
|
string |
TYPE_RUNNER
|
'runner' |
|
string |
TYPE_MESSENGER
|
'messenger' |
|
string |
TYPE_NONE
|
'no process' |
private static
|
$instance |
|
|
private
integer
|
$_processId | 0 |
|
private
array
|
$_data | array(
'data' => array(), // actual source for $this->data for __get() and __set()
'avg_time' => 15, // average time in seconds between calls to $this->_save(), total_time/total_saves
'total_saves' => 0,
'total_time' => 0,
'heartbeat' => false, //timestamp of last save
'complete' => false,
'ready' => false,
) |
|
private
resource
|
$_fd | null |
#
actual source for $this->fd for __get() |
private
boolean
|
$_transaction | false |
|
private
boolean
|
$_runner | false |
|
private
boolean
|
$_newProcess | false |
|
private
mixed
|
$_max_exec_time |
|
|
private
mixed
|
$_chunk_time |
|
|
private
array
|
$_files | array(
'new' => array(
'data' => '', // file with $this->data serialized.
'file' => '', // $this->fd points here. File is locked by a live Runner permanently.
),
'old' => array( // A second pair of data files to ensure persistence.
'data' => '',
'file' => '',
),
'flock_ok' => '', // this file exists if we're sure that flock works in this system.
) |
|
private
float
|
$_heartbeat | 0.0 |
|
protected
integer
|
$_read_attempt_limit | 5 |