Giter Site home page Giter Site logo

graceful-death's Introduction

Graceful Death Build Status

As you may know, catching fatal errors in PHP is extremely painful aka nearly impossible. This is a library that (partially) solves this issue

Usage

<?php

require __DIR__ . "/vendor/autoload.php";

// The output will be:
//
// Yes, I can ;-)

GracefulDeath::around(function() {
    try {
        // Avoid to print the error in order to have clean output, don't try this at home :-)
        error_reporting(E_ALL ^ E_ERROR);
        // Creating an instance of an unknown class will cause a fatal error
        new UnknownClass();
    } catch(Exception $e) {
        // A fatal error is uncatchable
        echo "You cannot catch this, AHAHAHAHA!!!\n";
    }
})
->afterViolentDeath("Yes, I can ;-)\n")
->run();

Scenario

You have a piece of code that potentially can trigger a fatal error and you want to be able to clean up after it or retry it with some policy. With GracefulDeath you can put this piece of code in a closure and pass it as a parameter to the GracefulDeath::around static method. This static method returns an instance of a builder that let you configure how GracefulDeath will behave. With afterViolentDeath you can configure an handler that will be called whenever a fatal error is triggered. The handler could be

  • An integer: the process will terminate with this integer as status code
  • A string: the string will be printed on standard output (like in this example)
  • A closure: the closure will be executed and its return value will be used as return value of the run method. The closure signature is function($status, $stdout, $stderr) where $status is the exit status of the code passed to GracefulDeath::around

There are a few other method that can be used to configure GracefulDeath

  • afterNaturalDeath: like afterViolentDeath but used to configure an handler that will be called only when no errors are triggered

  • afterDeath: used to configure an handler (like afterViolentDeath and afterNaturalDeath) that will be called after the code passed to GracefulDeath::around is terminated

  • reanimationPolicy: used to configure the reanimation policy aka something that will be used to decide if the code passed to GracefulDeath::around should be executed again after a fatal error. The reanimation policy could be

    • A boolean: if true it will retry forever, if false it will never retry (default)
    • An integer: the number of times the code will be executed. The code will not be execute again if either the code terminates without error or the number of executions exceeds the number passed as argument
    • A closure: if the closure returns true the code will be executed again. The closure signature is function($status, $attempts, $stdout, $stderr)
      • $status: the exit status of the code passed to GracefulDeath::around
      • $attempts: how many times the code has been executed (think how many previous lives), starts at 1
      • $stdout: what the code passed to GracefulDeath::around printed on stdout
      • $stderr: what the code passed to GracefulDeath::around printed on stderr

    There are a few reanimation policies ready to be used

    • doNotReanimate: this is the default behaviour so not so useful to use but could be good for documentation or to make the code more explicit
    • giveMeAnotherChance: it will reanimate the child process only one time
    • liveForever: it will always reanimate the child process. If you use this reanimation policy don't forget also to use avoidFutileMedicalCare to avoid to continually reanimate a child process that is broken
  • doNotCaptureOutput: avoid to capture stdout and stderr. Note that if output is not captured then it could not be given to the reanimationPolicy closure

  • doNotEchoOutput: discard the (if any) captured output

  • avoidFutileMedicalCare($numberOfFailures, $inAmountOfTime): avoid to reanimate a process that died too many times ($numberOfFailures default to 6) in a small amount of time ($inAmountOfTime default 60 seconds)

For all the options and methods look at the examples or at the tests 😄

Use Cases

  • You have a long running process that leaks memory (see examples/memory_leak.php)
  • You can use graceful-death as a supervisor, for that use ->liveForever() to always reanimate the child process and don't forget to use ->avoidFutileMedicalCare() to avoid to continually reanimate a child process that is broken

How Does It Work?

When run is called the process forks, the child process will execute the code passed to GracefulDeath::around, the parent process will act as a supervisor of the child. The supervisor will wait until the child dies and will act accordingly to the exit status and the given configuration.

Gotcha

It only works where pcntl_* function are available.

Self-Promotion

If you like this project, then consider to:

graceful-death's People

Contributors

gabrielelana avatar jnardiello avatar pborreli avatar

Stargazers

Luca Giacalone avatar Kanhaiya Murarka avatar Garrett W. avatar Bogdan Rancichi avatar Carlo Denaro avatar Andrea Sangiorgio avatar Tim (robske_110) avatar Angus H. avatar Sebastian Fahrenkrog avatar Dominik Ritter avatar Daniele Megna avatar devsmt avatar Nicolò Pignatelli avatar Yuriy Golikov avatar Jamolkhon Khakimov avatar Eric Colinet avatar Alexander Miertsch avatar Cédric Dugat avatar Matt Ketmo avatar Wojciech Zalewski avatar Mirko Bonadei avatar Manuele Menozzi avatar  avatar Alejandro Schmechel avatar Gilvan Ritter avatar Andrea Delfino avatar Francesco Dominidiato avatar Oleg Lobach avatar Marcos Sader avatar Matteo Magni avatar Oleksii Strizhak avatar Artem avatar Konstantin Kopachev avatar Mohamed Karnichi avatar Alexandr avatar Francesco Fullone avatar Aleksandr Manichev avatar Alexander Grimalovsky avatar Konstantin Myakshin avatar Valerii Baleiko avatar Gabriele Giuranno avatar Zan Baldwin avatar Davide Marrone avatar Emanuele Minotto avatar Andy Librian avatar Francesco Trucchia avatar Jacek avatar Ariel Ferrandini avatar Anton Medvedev avatar Peter Suhm avatar Luciano Mammino avatar Gábor Egyed avatar Ike Devolder avatar Matteo Giachino avatar Francesco Mosca avatar Marco Pivetta avatar

Watchers

Aurimas Baubkus avatar Konstantin Myakshin avatar Mirko Bonadei avatar  avatar James Cloos avatar Francesco Dominidiato avatar  avatar Kanhaiya Murarka avatar  avatar

Forkers

pborreli

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.