All Projects → webmozarts → Console Parallelization

webmozarts / Console Parallelization

Licence: mit
Enables the parallelization of Symfony Console commands.

Projects that are alternatives of or similar to Console Parallelization

Console
The Console component eases the creation of beautiful and testable command line interfaces.
Stars: ✭ 8,988 (+5314.46%)
Mutual labels:  console, symfony
Laravel Zero
A PHP framework for console artisans
Stars: ✭ 2,821 (+1599.4%)
Mutual labels:  console, symfony
Consolebundle
Commandline interface in browser for Symfony2
Stars: ✭ 138 (-16.87%)
Mutual labels:  console, symfony
Drupal Console
The Drupal CLI. A tool to generate boilerplate code, interact with and debug Drupal.
Stars: ✭ 913 (+450%)
Mutual labels:  console, symfony
Package Builder
[READ-ONLY] Speed up your package DI containers integration and console apps to Symfony and Nette
Stars: ✭ 152 (-8.43%)
Mutual labels:  console, symfony
Consoletableext
A fluent library to print out a nicely formatted table in a console application C#
Stars: ✭ 158 (-4.82%)
Mutual labels:  console
Tty Box
Draw various frames and boxes in your terminal window
Stars: ✭ 161 (-3.01%)
Mutual labels:  console
Enqueue Dev
Message Queue, Job Queue, Broadcasting, WebSockets packages for PHP, Symfony, Laravel, Magento. DEVELOPMENT REPOSITORY - provided by Forma-Pro
Stars: ✭ 1,977 (+1090.96%)
Mutual labels:  symfony
Dotnet Console Games
Game examples implemented in .NET console applications primarily for educational purposes.
Stars: ✭ 157 (-5.42%)
Mutual labels:  console
Mime
The MIME component allows manipulating MIME types.
Stars: ✭ 2,174 (+1209.64%)
Mutual labels:  symfony
2fa
Two-factor authentication for Symfony applications 🔐 (bunde version ≥ 5)
Stars: ✭ 162 (-2.41%)
Mutual labels:  symfony
Future.apply
🚀 R package: future.apply - Apply Function to Elements in Parallel using Futures
Stars: ✭ 159 (-4.22%)
Mutual labels:  parallelization
Serializer
With the Serializer component it's possible to handle serializing data structures, including object graphs, into array structures or other formats like XML and JSON. It can also handle deserializing XML and JSON back to object graphs.
Stars: ✭ 2,021 (+1117.47%)
Mutual labels:  symfony
Tinyconsole
📱💬🚦 TinyConsole is a micro-console that can help you log and display information inside an iOS application, where having a connection to a development computer is not possible.
Stars: ✭ 1,929 (+1062.05%)
Mutual labels:  console
Controllerextrabundle
Controller extra Bundle for Symfony2
Stars: ✭ 157 (-5.42%)
Mutual labels:  symfony
Nelmioapidocbundle
Generates documentation for your REST API from annotations
Stars: ✭ 2,009 (+1110.24%)
Mutual labels:  symfony
Polyfill Php73
This component provides functions unavailable in releases prior to PHP 7.3.
Stars: ✭ 2,121 (+1177.71%)
Mutual labels:  symfony
Symfony Bootstrapped
⚡️ Symfony with tools
Stars: ✭ 160 (-3.61%)
Mutual labels:  symfony
Console
Management UI for MinIO and MinIO operator
Stars: ✭ 159 (-4.22%)
Mutual labels:  console
React Console Emulator
👨‍💻 A simple, powerful and highly customisable Unix terminal emulator for React.
Stars: ✭ 160 (-3.61%)
Mutual labels:  console

Parallelization for the Symfony Console

This library supports the parallelization of Symfony Console commands.

How it works

When you launch a command with multi-processing enabled (--processes 2), a master process fetches items and distributes them across the given number of child processes. Child processes are killed after a fixed number of items (a segment) in order to prevent them from slowing down over time.

Optionally, the work of child processes can be split down into further chunks (batches). You can perform certain work before and after each of these batches (for example flushing changes to the database) in order to optimize the performance of your command.

Installation

Use Composer to install the package:

$ composer require webmozarts/console-parallelization

Example

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Webmozarts\Console\Parallelization\Parallelization;

class ImportMoviesCommand extends ContainerAwareCommand
{
    use Parallelization;

    protected static $defaultName = 'import:movies';

    protected function configure(): void
    {
        self::configureParallelization($this);
    }

    protected function fetchItems(InputInterface $input): array
    {
        // open up the file and read movie data...

        // return items as strings
        return [
            '{"id": 1, "name": "Star Wars"}',
            '{"id": 2, "name": "Django Unchained"}',
            // ...
        ];
    }

    protected function runSingleCommand(string $item, InputInterface $input, OutputInterface $output): void
    {
        $movieData = unserialize($item);
   
        // insert into the database
    }

    protected function runAfterBatch(InputInterface $input, OutputInterface $output, array $items): void
    {
        // flush the database and clear the entity manager
    }

    protected function getItemName(int $count): string
    {
        return 1 === $count ? 'movie' : 'movies';
    }
}

You can run this command like a regular Symfony Console command:

$ bin/console import:movies
Processing 2768 movies in segments of 2768, batches of 50, 1 round, 56 batches in 1 process

 2768/2768 [============================] 100% 56 secs/56 secs 32.0 MiB
            
Processed 2768 movies.

Or, if you want, you can run the command using parallelization:

$ bin/console import:movies --processes 2
Processing 2768 movies in segments of 50, batches of 50, 56 rounds, 56 batches in 2 processes

 2768/2768 [============================] 100% 31 secs/31 secs 32.0 MiB
            
Processed 2768 movies.

Items

The master process fetches all the items that need to be processed and passes them to the child processes through their Standard Input. Hence items must fulfill two requirements:

  • Items must be strings
  • Items must not contain newlines

Typically, you want to keep items small in order to offload processing from the master process to the child process. Some typical examples for items:

  • The master process reads a file and passes the lines to the child processes
  • The master processes fetches IDs of database rows that need to be updated and passes them to the child processes

Segments

When you run a command with multi-processing enabled, the items returned by fetchItems() are split into segments of a fixed size. Each child processes processes a single segment and kills itself after that.

By default, the segment size is the same as the batch size (see below), but you can try to tweak the performance of your command by choosing a different segment size (ideally a multiple of the batch size). You can do so by overriding the getSegmentSize() method:

protected function getSegmentSize(): int
{
    return 250;
}

Batches

By default, the batch size and the segment size is the same. If desired, you can however choose a smaller batch size than the segment size and run custom code before or after each batch. You will typically do so in order to flush changes to the database or free resources that you don't need anymore.

To run code before/after each batch, override the hooks runBeforeBatch() and runAfterBatch():

protected function runBeforeBatch(InputInterface $input, OutputInterface $output, array $items): void
{
    // e.g. fetch needed resources collectively
}

protected function runAfterBatch(InputInterface $input, OutputInterface $output, array $items): void
{
    // e.g. flush database changes and free resources
}

You can customize the default batch size of 50 by overriding the getBatchSize() method:

protected function getBatchSize(): int
{
    return 150;
}

Hooks

The Parallelization trait supports more hooks than the one mentioned in the last section. In the table below you can find a complete list of them:

Method Scope Description
runBeforeFirstCommand($input, $output) Master process Run before any child process is spawned
runAfterLastCommand($input, $output) Master process Run after all child processes have completed
runBeforeBatch($input, $output, $items) Child process Run before each batch in the child process
runAfterBatch($input, $output, $items) Child process Run after each batch in the child process

Authors

Contribute

Contributions to the package are always welcome!

License

All contents of this package are licensed under the MIT license.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].