Erik van Velzen wrote on 28/10/2015 13:28:
try {
$scope = new ScopeGuard;
$scope->onSucces(function() { logTransactionOne(); });
$scope->onFailure(function() { rollbackTransationOne(); });
doTransactionOne();
$scope->onSuccess(function() { logTransactionTwo(); });
$scope->onFailure(function() { rollbackTransactionTwo(); });
$scope->onExit(function() { cleanupTransactionTwo(); });
doTransactionTwo();
}
catch (\Throwable $e) {
$scope->callFailureHandlers();
throw $e;
}
finally {
$scope->callExitHandlers();
}
$scope->callSuccessHandlers();
Did you see Johannes' suggestion re explicit success vs implicit failure?
$scope = new ScopeGuard;
$scope->onSucces(function() { logTransactionOne(); });
$scope->onFailure(function() { rollbackTransationOne(); });
doTransactionOne();
$scope->onSuccess(function() { logTransactionTwo(); });
$scope->onFailure(function() { rollbackTransactionTwo(); });
$scope->onExit(function() { cleanupTransactionTwo(); });
doTransactionTwo();
$scope->registerSuccess();
The ScopeGuard's destructor can now detect the condition:
if ( $this->success_registered ) {
// Function reached checkpoint for this scope
$this->callSuccessHandlers();
} else {
// Function aborted early, due to a throw or early return
$this->callExitHandlers();
}
$this->callExitHandlers();
No boilerplate throw-catch needed, works even if there is already a catch or
finally within the function's definition.
In fact, I kind of want to use this somewhere now... ;)
Regards,
--
Rowan Collins
[IMSoP]
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php