Merge pull request #4420 from Elsensee/ticket/14742-32x

[ticket/14742-32x] Further improvements to migrator
This commit is contained in:
Marc Alexander 2016-08-21 09:44:37 +02:00
commit 76748183bb
8 changed files with 79 additions and 68 deletions

View file

@ -152,7 +152,7 @@ class config implements \phpbb\db\migration\tool\tool_interface
break; break;
case 'reverse': case 'reverse':
// It's like double negative // Reversing a reverse is just the call itself
$call = array_shift($arguments); $call = array_shift($arguments);
break; break;
} }

View file

@ -117,7 +117,7 @@ class config_text implements \phpbb\db\migration\tool\tool_interface
break; break;
case 'reverse': case 'reverse':
// It's like double negative // Reversing a reverse is just the call itself
$call = array_shift($arguments); $call = array_shift($arguments);
break; break;
} }

View file

@ -445,7 +445,7 @@ class module implements \phpbb\db\migration\tool\tool_interface
break; break;
case 'reverse': case 'reverse':
// It's like double negative // Reversing a reverse is just the call itself
$call = array_shift($arguments); $call = array_shift($arguments);
break; break;
} }

View file

@ -639,7 +639,7 @@ class permission implements \phpbb\db\migration\tool\tool_interface
break; break;
case 'reverse': case 'reverse':
// It's like double negative // Reversing a reverse is just the call itself
$call = array_shift($arguments); $call = array_shift($arguments);
break; break;
} }

View file

@ -362,8 +362,10 @@ class migrator
$total_time = (is_array($state['migration_data_state']) && isset($state['migration_data_state']['_total_time'])) ? $total_time = (is_array($state['migration_data_state']) && isset($state['migration_data_state']['_total_time'])) ?
$state['migration_data_state']['_total_time'] : 0.0; $state['migration_data_state']['_total_time'] : 0.0;
$elapsed_time = microtime(true); $elapsed_time = microtime(true);
$steps = $this->helper->get_schema_steps($migration->update_schema()); $steps = $this->helper->get_schema_steps($migration->update_schema());
$result = $this->process_data_step($steps, $state['migration_data_state']); $result = $this->process_data_step($steps, $state['migration_data_state']);
$elapsed_time = microtime(true) - $elapsed_time; $elapsed_time = microtime(true) - $elapsed_time;
$total_time += $elapsed_time; $total_time += $elapsed_time;
@ -397,7 +399,9 @@ class migrator
$total_time = (is_array($state['migration_data_state']) && isset($state['migration_data_state']['_total_time'])) ? $total_time = (is_array($state['migration_data_state']) && isset($state['migration_data_state']['_total_time'])) ?
$state['migration_data_state']['_total_time'] : 0.0; $state['migration_data_state']['_total_time'] : 0.0;
$elapsed_time = microtime(true); $elapsed_time = microtime(true);
$result = $this->process_data_step($migration->update_data(), $state['migration_data_state']); $result = $this->process_data_step($migration->update_data(), $state['migration_data_state']);
$elapsed_time = microtime(true) - $elapsed_time; $elapsed_time = microtime(true) - $elapsed_time;
$total_time += $elapsed_time; $total_time += $elapsed_time;
@ -421,7 +425,10 @@ class migrator
} }
catch (\phpbb\db\migration\exception $e) catch (\phpbb\db\migration\exception $e)
{ {
// Revert the schema changes // Reset data state and revert the schema changes
$state['migration_data_state'] = '';
$this->set_migration_state($name, $state);
$this->revert_do($name); $this->revert_do($name);
throw $e; throw $e;
@ -506,8 +513,10 @@ class migrator
$total_time = (is_array($state['migration_data_state']) && isset($state['migration_data_state']['_total_time'])) ? $total_time = (is_array($state['migration_data_state']) && isset($state['migration_data_state']['_total_time'])) ?
$state['migration_data_state']['_total_time'] : 0.0; $state['migration_data_state']['_total_time'] : 0.0;
$elapsed_time = microtime(true); $elapsed_time = microtime(true);
$steps = array_merge($this->helper->reverse_update_data($migration->update_data()), $migration->revert_data()); $steps = array_merge($this->helper->reverse_update_data($migration->update_data()), $migration->revert_data());
$result = $this->process_data_step($steps, $state['migration_data_state']); $result = $this->process_data_step($steps, $state['migration_data_state']);
$elapsed_time = microtime(true) - $elapsed_time; $elapsed_time = microtime(true) - $elapsed_time;
$total_time += $elapsed_time; $total_time += $elapsed_time;
@ -539,8 +548,10 @@ class migrator
$total_time = (is_array($state['migration_data_state']) && isset($state['migration_data_state']['_total_time'])) ? $total_time = (is_array($state['migration_data_state']) && isset($state['migration_data_state']['_total_time'])) ?
$state['migration_data_state']['_total_time'] : 0.0; $state['migration_data_state']['_total_time'] : 0.0;
$elapsed_time = microtime(true); $elapsed_time = microtime(true);
$steps = $this->helper->get_schema_steps($migration->revert_schema()); $steps = $this->helper->get_schema_steps($migration->revert_schema());
$result = $this->process_data_step($steps, $state['migration_data_state']); $result = $this->process_data_step($steps, $state['migration_data_state']);
$elapsed_time = microtime(true) - $elapsed_time; $elapsed_time = microtime(true) - $elapsed_time;
$total_time += $elapsed_time; $total_time += $elapsed_time;
@ -585,6 +596,11 @@ class migrator
*/ */
protected function process_data_step($steps, $state, $revert = false) protected function process_data_step($steps, $state, $revert = false)
{ {
if (sizeof($steps) === 0)
{
return true;
}
$state = is_array($state) ? $state : false; $state = is_array($state) ? $state : false;
// reverse order of steps if reverting // reverse order of steps if reverting
@ -593,45 +609,26 @@ class migrator
$steps = array_reverse($steps); $steps = array_reverse($steps);
} }
end($steps); $step = $last_result = 0;
$last_step_identifier = key($steps);
foreach ($steps as $step_identifier => $step)
{
$last_result = 0;
if ($state) if ($state)
{ {
// Continue until we reach the step that matches the last step called $step = $state['step'];
if ($state['step'] != $step_identifier)
{
continue;
}
// We send the result from last time to the callable function // We send the result from last time to the callable function
$last_result = $state['result']; $last_result = $state['result'];
// Set state to false since we reached the point we were at
$state = false;
// There is a tendency to get stuck in some cases
if ($last_result === null || $last_result === true)
{
continue;
}
} }
try try
{ {
// Result will be null or true if everything completed correctly // Result will be null or true if everything completed correctly
// After any schema update step we allow to pause, since // Stop after each update step, to let the updater control the script runtime
// database changes can take quite some time $result = $this->run_step($steps[$step], $last_result, $revert);
$result = $this->run_step($step, $last_result, $revert); if (($result !== null && $result !== true) || $step + 1 < sizeof($steps))
if (($result !== null && $result !== true) ||
(strpos($step[0], 'dbtools') === 0 && $step_identifier !== $last_step_identifier))
{ {
return array( return array(
'result' => $result, 'result' => $result,
'step' => $step_identifier, // Move on if the last call finished
'step' => ($result !== null && $result !== true) ? $step : $step + 1,
); );
} }
} }
@ -641,18 +638,17 @@ class migrator
foreach ($steps as $reverse_step_identifier => $reverse_step) foreach ($steps as $reverse_step_identifier => $reverse_step)
{ {
// If we've reached the current step we can break because we reversed everything that was run // If we've reached the current step we can break because we reversed everything that was run
if ($reverse_step_identifier == $step_identifier) if ($reverse_step_identifier == $step)
{ {
break; break;
} }
// Reverse the step that was run // Reverse the step that was run
$this->run_step($reverse_step, false, !$revert); $result = $this->run_step($reverse_step, false, !$revert);
} }
throw $e; throw $e;
} }
}
return true; return true;
} }

View file

@ -15,11 +15,11 @@ namespace phpbb\db\output_handler;
interface migrator_output_handler_interface interface migrator_output_handler_interface
{ {
const VERBOSITY_QUIET = 0; const VERBOSITY_QUIET = 16;
const VERBOSITY_NORMAL = 1; const VERBOSITY_NORMAL = 32;
const VERBOSITY_VERBOSE = 2; const VERBOSITY_VERBOSE = 64;
const VERBOSITY_VERY_VERBOSE = 3; const VERBOSITY_VERY_VERBOSE = 128;
const VERBOSITY_DEBUG = 4; const VERBOSITY_DEBUG = 256;
/** /**
* Write output using the configured closure. * Write output using the configured closure.

View file

@ -198,6 +198,16 @@ class cli_iohandler extends iohandler_base
if ($this->output->getVerbosity() === OutputInterface::VERBOSITY_NORMAL) if ($this->output->getVerbosity() === OutputInterface::VERBOSITY_NORMAL)
{ {
if ($this->progress_bar !== null)
{
// Symfony's ProgressBar is immutable regarding task_count, so delete the old and create a new one.
$this->progress_bar->clear();
}
else
{
$this->io->newLine(2);
}
$this->progress_bar = $this->io->createProgressBar($task_count); $this->progress_bar = $this->io->createProgressBar($task_count);
$this->progress_bar->setFormat( $this->progress_bar->setFormat(
" %current:3s%/%max:-3s% %bar% %percent:3s%%\n" . " %current:3s%/%max:-3s% %bar% %percent:3s%%\n" .
@ -212,7 +222,6 @@ class cli_iohandler extends iohandler_base
} }
$this->progress_bar->setMessage(''); $this->progress_bar->setMessage('');
$this->io->newLine(2);
$this->progress_bar->start(); $this->progress_bar->start();
} }
} }

View file

@ -158,18 +158,23 @@ class update extends task_base
try try
{ {
$this->migrator->update(); $this->migrator->update();
$progress_count++;
$last_run_migration = $this->migrator->get_last_run_migration(); $last_run_migration = $this->migrator->get_last_run_migration();
if (isset($last_run_migration['effectively_installed']) && $last_run_migration['effectively_installed']) if (isset($last_run_migration['effectively_installed']) && $last_run_migration['effectively_installed'])
{ {
$progress_count += 2; // We skipped two step, so increment $progress_count by another one
}
else if (($last_run_migration['task'] === 'process_schema_step' && $last_run_migration['state']['migration_schema_done']) ||
($last_run_migration['task'] === 'process_data_step' && $last_run_migration['state']['migration_data_done']))
{
$progress_count++; $progress_count++;
} }
else if (($last_run_migration['task'] === 'process_schema_step' && !$last_run_migration['state']['migration_schema_done']) ||
($last_run_migration['task'] === 'process_data_step' && !$last_run_migration['state']['migration_data_done']))
{
// We just run a step that wasn't counted yet so make it count
$migration_step_count++;
}
$this->iohandler->set_task_count($migration_step_count);
$this->installer_config->set_task_progress_count($migration_step_count);
$this->iohandler->set_progress('STAGE_UPDATE_DATABASE', $progress_count); $this->iohandler->set_progress('STAGE_UPDATE_DATABASE', $progress_count);
} }
catch (exception $e) catch (exception $e)
@ -184,6 +189,7 @@ class update extends task_base
if ($this->installer_config->get_time_remaining() <= 0 || $this->installer_config->get_memory_remaining() <= 0) if ($this->installer_config->get_time_remaining() <= 0 || $this->installer_config->get_memory_remaining() <= 0)
{ {
$this->installer_config->set('database_update_count', $progress_count); $this->installer_config->set('database_update_count', $progress_count);
$this->installer_config->set('database_update_migration_steps', $migration_step_count);
throw new resource_limit_reached_exception(); throw new resource_limit_reached_exception();
} }
} }