Coding standards
Security in ResourceSpace
Developer reference
Database
User api session functions
Geolocation functions
Storage test functions

storage_test_advance()

Description

Advance at most eight workload units or 200 ms; directory operations return after one unit.
Cleanup uses at most sixteen entries.
Work stops after 45 seconds wall time, leaving a nominal 15 seconds for cleanup.
Filesystem syscalls cannot be interrupted portably by PHP.

Parameters

ColumnTypeDefaultDescription
&$state array
$cancel bool Request cancellation and cleanup.
$state array Mutable test state, always saved even on an operation failure.

Return

void

Location

include/storage_test_functions.php lines 463 to 532

Definition

 
function storage_test_advance(array &$state, bool $cancel = false): void
{
    
$previous = $GLOBALS['use_error_exception'] ?? false;
    
$GLOBALS['use_error_exception'] = true;
    
$start = hrtime(true) / 1e9;
    
$deadline = $start + 0.2;
    if ((
$cancel || microtime(true) - $state['started'] >= 45) && $state['stage'] !== 'cleanup') {
        
$state['stage'] = 'cleanup';
        
$state['outcome'] = $cancel ? 'cancelled' : 'limited';
    }
    try {
        if (
$state['stage'] === 'cleanup') {
            if ((
$state['error'] ?? '') === 'storage_test_cleanup_error') {
                unset(
$state['error']);
            }
            if (
storage_test_cleanup($state, $deadline)) {
                
$state['stage'] = 'done';
                
$state['elapsed'] = microtime(true) - $state['started'];
            }
        } else {
            
$stages = storage_test_stages();
            
$stage = $state['stage'];
            
$complete = false;
            
$units = in_array($stage, ['directories', 'enumerate'], true) ? 1 : 8;
            for (
$i = 0; $i < $units && hrtime(true) / 1e9 < $deadline; ++$i) {
                if (
microtime(true) - $state['started'] >= 45) {
                    break;
                }
                
$complete = storage_test_unit($state);
                if (
$complete || $state['stage_time'] + hrtime(true) / 1e9 - $start >= $stages[$stage]) {
                    break;
                }
            }
            
$state['stage_time'] += hrtime(true) / 1e9 - $start;
            if (
$complete || $state['stage_time'] >= $stages[$stage]) {
                
$state['limited'] = $state['limited'] || !$complete;
                
$names = array_keys($stages);
                
$state['stage'] = $names[array_search($stage, $names, true) + 1] ?? 'cleanup';
                
$state['cursor'] = 0;
                
$state['stage_time'] = 0;
            }
        }
    } catch (
Throwable $e) {
        
debug('Storage performance test: ' . $state['stage'] . ' failed (' . get_class($e)
            . 
', line ' . $e->getLine() . ').');
        
$state['stage'] = 'cleanup';
        
$state['outcome'] = 'error';
        
$state['error'] = 'storage_test_io_error';
        
// Retain the registry even if cleanup is blocked, so later runs cannot start over it.
        
$GLOBALS['use_error_exception'] = true;
        try {
            if (
storage_test_cleanup($state, $deadline)) {
                
$state['stage'] = 'done';
                
$state['elapsed'] = microtime(true) - $state['started'];
            }
        } catch (
Throwable $cleanup_error) {
            
$state['error'] = 'storage_test_cleanup_error';
            
debug('Storage performance test: cleanup blocked (' . get_class($cleanup_error)
                . 
', line ' . $cleanup_error->getLine() . ').');
        }
    } finally {
        ++
$state['sequence'];
        
$state['updated'] = time();
        try {
            
storage_test_save($state);
        } finally {
            
$GLOBALS['use_error_exception'] = $previous;
        }
    }
}

This article was last updated 13th November 2026 13:05 Europe/London time based on the source file dated 13th November 2026 11:40 Europe/London time.