Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Spork Laravel Package

kriswallsmith/spork

Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require kriswallsmith/spork
    

    Add to composer.json under require-dev if using for testing.

  2. Basic Usage:

    use Kris\Spork\Spork;
    
    $spork = new Spork();
    $pid = $spork->fork();
    if ($pid === 0) {
        // Child process logic
        exit(0);
    } else {
        // Parent process logic
        $spork->wait();
    }
    
  3. First Use Case:

    • Parallel Task Execution: Run time-consuming tasks (e.g., image processing, API calls) in parallel.
    • Example:
      $spork = new Spork();
      $handles = [];
      for ($i = 0; $i < 5; $i++) {
          $pid = $spork->fork();
          if ($pid === 0) {
              // Child process
              processLargeFile("file_$i");
              exit(0);
          }
          $handles[] = $pid;
      }
      $spork->waitAll($handles);
      

Implementation Patterns

Common Workflows

  1. Resource-Intensive Tasks:

    • Offload CPU-heavy operations (e.g., video encoding, data transformations) to child processes.
    • Example:
      $spork = new Spork();
      $pid = $spork->fork();
      if ($pid === 0) {
          $result = runComplexCalculation();
          file_put_contents('/tmp/result', $result);
          exit(0);
      }
      
  2. Concurrent HTTP Requests:

    • Useful for scraping or batch API calls.
    • Example:
      $urls = ['url1', 'url2', 'url3'];
      $spork = new Spork();
      $handles = [];
      foreach ($urls as $url) {
          $pid = $spork->fork();
          if ($pid === 0) {
              $response = file_get_contents($url);
              file_put_contents("/tmp/{$url}.html", $response);
              exit(0);
          }
          $handles[] = $pid;
      }
      $spork->waitAll($handles);
      
  3. Process Isolation:

    • Run untrusted or risky code in isolated processes.
    • Example:
      $spork = new Spork();
      $pid = $spork->fork();
      if ($pid === 0) {
          // Untrusted code here
          eval($_POST['code']); // Hypothetical risky operation
          exit(0);
      }
      

Integration Tips

  1. Laravel Service Providers:

    • Register Spork as a singleton in AppServiceProvider:
      $this->app->singleton(Spork::class, function () {
          return new Spork();
      });
      
    • Inject via constructor:
      public function __construct(private Spork $spork) {}
      
  2. Queue Workers:

    • Use Spork in Laravel Queues for parallel job execution.
    • Example:
      public function handle() {
          $spork = app(Spork::class);
          $pid = $spork->fork();
          if ($pid === 0) {
              // Heavy processing
              $this->processData();
              exit(0);
          }
      }
      
  3. Signal Handling:

    • Gracefully handle child processes with signals (e.g., SIGTERM).
    • Example:
      $spork = new Spork();
      $pid = $spork->fork();
      if ($pid > 0) {
          pcntl_signal(SIGTERM, function () use ($spork, $pid) {
              $spork->kill($pid);
          });
      }
      

Gotchas and Tips

Pitfalls

  1. Zombie Processes:

    • Always call wait() or waitAll() to avoid orphaned processes.
    • Example of leak:
      $spork->fork(); // Forgetting to wait!
      
  2. Shared Memory Issues:

    • Avoid shared memory between parent/child (e.g., Laravel’s session, cache).
    • Use ignore_user_abort(true) if needed for long-running children.
  3. Signal Conflicts:

    • Spork may interfere with Laravel’s built-in signal handling (e.g., graceful shutdown).
    • Disable Laravel’s signal handling if using Spork for critical processes:
      $this->app['events']->listen('terminating', function () {
          // Custom cleanup
      });
      
  4. Resource Limits:

    • Child processes inherit PHP’s memory_limit and max_execution_time.
    • Adjust via ini_set() in the child:
      if ($pid === 0) {
          ini_set('memory_limit', '512M');
          // ...
      }
      

Debugging

  1. Logging:

    • Log process IDs ($pid) for debugging:
      error_log("Forked child with PID: $pid");
      
  2. Process Inspection:

    • Use ps aux | grep php to check for rogue processes.
    • Kill manually if needed:
      kill -9 <PID>
      
  3. Error Handling:

    • Wrap child logic in try-catch to prevent silent failures:
      if ($pid === 0) {
          try {
              // Risky operations
          } catch (\Throwable $e) {
              file_put_contents('/tmp/error.log', $e->getMessage());
              exit(1);
          }
      }
      

Extension Points

  1. Custom Process Management:

    • Extend Spork to add features like process timeouts:
      class TimeoutSpork extends Spork {
          public function forkWithTimeout(callable $callback, int $timeout) {
              $pid = $this->fork();
              if ($pid === 0) {
                  $callback();
                  exit(0);
              }
              $this->waitFor($pid, $timeout);
              return $pid;
          }
      
          private function waitFor(int $pid, int $timeout) {
              $start = time();
              while (time() - $start < $timeout && pcntl_waitpid($pid, $status, WNOHANG) === 0) {
                  usleep(100000);
              }
              if (time() - $start >= $timeout) {
                  $this->kill($pid);
              }
          }
      }
      
  2. Inter-Process Communication (IPC):

    • Use shared files or sockets for parent-child communication:
      if ($pid === 0) {
          file_put_contents('/tmp/child_data', serialize($data));
          exit(0);
      } else {
          $spork->wait();
          $data = unserialize(file_get_contents('/tmp/child_data'));
      }
      
  3. Laravel Artisan Commands:

    • Create a custom Artisan command for Spork-based tasks:
      php artisan spork:run --task=process --args="file1,file2"
      
    • Example command:
      class SporkRunCommand extends Command {
          protected $signature = 'spork:run {task} {args*}';
          public function handle() {
              $spork = app(Spork::class);
              $pid = $spork->fork();
              if ($pid === 0) {
                  $this->call("task:{$this->argument('task')}", ['args' => $this->argument('args')]);
                  exit(0);
              }
              $spork->wait();
          }
      }
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware