{"id":23219107,"url":"https://github.com/b2pweb/bdf-queue","last_synced_at":"2025-08-19T08:32:42.052Z","repository":{"id":36740190,"uuid":"229062326","full_name":"b2pweb/bdf-queue","owner":"b2pweb","description":"An abstraction layer for message broker in PHP","archived":false,"fork":false,"pushed_at":"2025-05-15T09:29:55.000Z","size":421,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"1.5","last_synced_at":"2025-07-19T08:04:35.362Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/b2pweb.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-12-19T13:39:39.000Z","updated_at":"2025-05-15T09:16:17.000Z","dependencies_parsed_at":"2024-12-18T15:38:07.588Z","dependency_job_id":null,"html_url":"https://github.com/b2pweb/bdf-queue","commit_stats":{"total_commits":65,"total_committers":4,"mean_commits":16.25,"dds":0.3846153846153846,"last_synced_commit":"c6890f98ae9da1de16f6954d3ee52cf3a94d5803"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/b2pweb/bdf-queue","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/b2pweb%2Fbdf-queue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/b2pweb%2Fbdf-queue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/b2pweb%2Fbdf-queue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/b2pweb%2Fbdf-queue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/b2pweb","download_url":"https://codeload.github.com/b2pweb/bdf-queue/tar.gz/refs/heads/1.5","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/b2pweb%2Fbdf-queue/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271121770,"owners_count":24702871,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-19T02:00:09.176Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-18T21:19:18.756Z","updated_at":"2025-08-19T08:32:41.558Z","avatar_url":"https://github.com/b2pweb.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Queue\n\nThis package provides 2 layers for abstraction of message broker.\n - A connection layer\n - A destination layer\n\n[![build](https://github.com/b2pweb/bdf-queue/actions/workflows/php.yml/badge.svg)](https://github.com/b2pweb/bdf-queue/actions/workflows/php.yml)\n[![codecov](https://codecov.io/github/b2pweb/bdf-queue/branch/1.5/graph/badge.svg?token=VOFSPEWYKX)](https://app.codecov.io/github/b2pweb/bdf-queue)\n[![Packagist Version](https://img.shields.io/packagist/v/b2pweb/bdf-queue.svg)](https://packagist.org/packages/b2pweb/bdf-queue)\n[![Total Downloads](https://img.shields.io/packagist/dt/b2pweb/bdf-queue.svg)](https://packagist.org/packages/b2pweb/bdf-queue)\n[![Type Coverage](https://shepherd.dev/github/b2pweb/bdf-queue/coverage.svg)](https://shepherd.dev/github/b2pweb/bdf-queue)\n\n#### Supports\n\n| Message Broker | Library      | Driver name    |\n|----------------|--------------|----------------|\n| Beanstalk      | Pheanstalk   | pheanstalk     |\n| Db             | Doctrine     | doctrine+(*)   |\n| Enqueue        | php-enqueue  | enqueue+(*)    |\n| Gearman        | Pecl Gearman | gearman        |\n| Kafka          | RdKafka      | rdkafka        |\n| Memory         |              | memory         |\n| Null           |              | null           |\n| RabbitMQ       | Amqp lib     | amqp-lib       |\n| Redis (Ext)    | PhpRedis     | redis+phpredis |\n| Redis          | PRedis       | redis+predis   |\n\n\n### Usage Instructions\n\n#### Produce messages\n\nFirst, create a new destination manager instance.\n\n```PHP\n\u003c?php\n\nuse Bdf\\Queue\\Connection\\Factory\\ResolverConnectionDriverFactory;\nuse Bdf\\Queue\\Connection\\Pheanstalk\\PheanstalkConnection;\nuse Bdf\\Queue\\Destination\\ConfigurationDestinationFactory;\nuse Bdf\\Queue\\Destination\\DestinationManager;\nuse Bdf\\Queue\\Destination\\DestinationFactory;\nuse Bdf\\Queue\\Serializer\\JsonSerializer;\n\n// Declare connections\n$driverFactory = new ResolverConnectionDriverFactory([\n    'foo' =\u003e [\n        'driver' =\u003e 'pheanstalk',\n        'host' =\u003e 'localhost',\n        'port' =\u003e '11300',\n        'additionalOption' =\u003e 'value',\n    ]\n    // OR use DSN 'foo' =\u003e 'pheanstalk://localhost:11300?additionalOption=value'\n]);\n\n// Declare drivers\n$driverFactory-\u003eaddDriverResolver('pheanstalk', function($config) {\n    //echo $config['connection'] displays \"foo\"\n    return new PheanstalkConnection($config['connection'], new JsonSerializer());\n});\n\n// Declare destination\n// You can also declare your custom destination that defined type of transport (queue, multi queues, topic, ...),\n// the connection to use, and the name of the queue(s) / topic(s) to use.\n// This example will use the queue driver of the \"foo\" connection defined above. And send / consume message on the queue named \"default\".\n$destinationFactory = new DestinationFactory(\n    $driverFactory,\n    ['my_destination' =\u003e 'queue://foo/default']\n);\n\n// To send a message to multiple destinations, you can use \"aggregate\" destination type.\n// You can use a wildcard to send to all destinations that match the pattern.\n// In this example, 'user' destination will be sent to the \"foo\" and \"bar\" queues, and to all topics that match the pattern \"*.user\"\n$destinationFactory = new DestinationFactory(\n    $driverFactory,\n    [\n        'foo' =\u003e 'queue://test/foo',\n        'bar' =\u003e 'queue://test/bar',\n        'a.user' =\u003e 'topic://a/user',\n        'b.user' =\u003e 'topic://b/user',\n        'user' =\u003e 'aggregate://foo,bar,*.user',\n    ]\n);\n\n// Create the manager\n$manager = new DestinationManager($driverFactory, $destinationFactory);\n```\n\nPush a basic message into the queue.\nThe consume should defined handler to process the message.\n\n```PHP\n\u003c?php\n\nuse Bdf\\Queue\\Message\\Message;\n\n$message = Message::create('Hello world');\n$message-\u003esetDestination('my_destination');\n// or use a lower level setting the connection and queue.\n$message = Message::create('Hello world', 'queue');\n$message-\u003esetConnection('foo');\n\n/** @var Bdf\\Queue\\Destination\\DestinationManager $manager */\n$manager-\u003esend($message);\n```\n\nUseful for monolithic application that needs to differ a process.\nPush a message job into the queue. The consumer will evaluate the job string and run the processor.\nIn this use case the producer and the receiver share the same model.\n\n```PHP\n\u003c?php\n$message = \\Bdf\\Queue\\Message\\Message::createFromJob(Mailer::class.'@send', ['body' =\u003e 'my content']);\n$message-\u003esetDestination('my_destination');\n\n/** @var Bdf\\Queue\\Destination\\DestinationManager $manager */\n$manager-\u003esend($message);\n```\n\n#### Available type for dsn destination\n\nThe class `Bdf\\Queue\\Destination\\DsnDestinationFactory` provides default type of destination:\n\n|Name           | Exemple                                          | Definition     | \n|---------------|--------------------------------------------------|----------------|\n|queue          | queue://connection_name/queue_name               | Publish and consume a single queue      |\n|queues         | queues://connection_name/queue1,queue2           | Only consume multi queues      |\n|topic          | topic://connection_name/topic                    | Publish and consume a topic. Pattern with wildcard are allowed for consumer use case only (ex: topic.*) |\n|topics         | topics://connection_name/topic1,topic2           | Only consume multi topics      |\n\nYou can declare your own type:\n\n```PHP\n\u003c?php\n\nuse Bdf\\Dsn\\DsnRequest;\nuse Bdf\\Queue\\Connection\\ConnectionDriverInterface;\nuse Bdf\\Queue\\Connection\\Factory\\ResolverConnectionDriverFactory;\n\n/** @var ResolverConnectionDriverFactory $driverFactory */\n\n$destinationFactory = new Bdf\\Queue\\Destination\\DsnDestinationFactory($driverFactory);\n$destinationFactory-\u003eregister('my_own_type', function(ConnectionDriverInterface $connection, DsnRequest $dsn) {\n    // ...\n});\n\n// use dsn as \"my_own_type://connection/queue_or_topic_name?option=\"\n```\n\n#### Consume messages\n\nThe consumer layer provides many tools for message handling.\nThe default stack of objects that will receive the message is:\n\n`consumer (ConsumerInterface) -\u003e receivers (ReceiverInterface) -\u003e processor (ProcessorInterface) -\u003e handler (callable)`\n\n- `consumer` has the strategy for reading the message from queue / topic. It also manage a graceful shutdown.\n- `receivers` is the stack of middlewares interacts with the envelope.\n- `processor` resolves the handler arguments. You can plug here your business logic and remove the handler layer.\nBy default processor injects 2 arguments in handlers: the message data and the envelope.\n- `handler` manages the business logic. Handler allows an interface less mode.\n\nAn example to consume a simple message:\n\n```PHP\n\u003c?php\n\nuse Bdf\\Queue\\Consumer\\Receiver\\ProcessorReceiver;\nuse Bdf\\Queue\\Destination\\DestinationManager;\nuse Bdf\\Queue\\Processor\\CallbackProcessor;\nuse Bdf\\Queue\\Processor\\MapProcessorResolver;\n\n// Create your processor and declare in a map:\n$myProcessor = new CallbackProcessor(function($data) {\n    echo $data;\n});\n$processorResolver = new MapProcessorResolver(['foo' =\u003e $myProcessor]);\n\n/** @var DestinationManager $manager */\n$manager-\u003ecreate('queue://foo')-\u003econsumer(new ProcessorReceiver($processorResolver))-\u003econsume(0);\n```\n\nConsume a job message:\n\n```PHP\n\u003c?php\n\nuse Bdf\\Instantiator\\Instantiator;\nuse Bdf\\Queue\\Consumer\\Receiver\\ProcessorReceiver;\nuse Bdf\\Queue\\Destination\\DestinationManager;\nuse Bdf\\Queue\\Processor\\JobHintProcessorResolver;\n\n/** @var Instantiator $instantiator */\n\n// The job should be provided from message to get the processor\n$processorResolver = new JobHintProcessorResolver($instantiator);\n\n/** @var DestinationManager $manager */\n$manager-\u003ecreate('queue://foo')-\u003econsumer(new ProcessorReceiver($processorResolver))-\u003econsume(0);\n```\n\n#### Create a handler\n\n```PHP\n\u003c?php\n\n/** @var Bdf\\Queue\\Destination\\DestinationManager $manager */\n\nclass MyHandler\n{\n    public function handle($data, \\Bdf\\Queue\\Message\\EnvelopeInterface $envelope)\n    {\n        echo $data; // Display 'foo'\n        \n        // Ack the message. Default behavior. The ack is sent before the call by the consumer.\n        $envelope-\u003eacknowledge();\n        \n        // Reject the message. It will be no more available. The message is rejected if and exception is thrown.\n        $envelope-\u003ereject();\n        \n        // Reject the message and send it back to the queue\n        $envelope-\u003ereject(true);\n    }\n}\n\n$message = \\Bdf\\Queue\\Message\\Message::createFromJob(MyHandler::class, 'foo', 'queue');\n$manager-\u003esend($message);\n```\n\nUse the synthax `\"Class@method\"` to determine the callable (By default the method is \"handle\")\nor register your handlers on a specific destination with the receiver builder:\n\n```PHP\n\u003c?php\n\nuse Bdf\\Queue\\Consumer\\Receiver\\Builder\\ReceiverBuilder;\nuse Bdf\\Queue\\Consumer\\Receiver\\Builder\\ReceiverLoader;\nuse Bdf\\Queue\\Consumer\\Receiver\\Builder\\ReceiverLoaderInterface;\nuse Psr\\Container\\ContainerInterface;\n\n/** @var ContainerInterface $container */\n/** @var Bdf\\Queue\\Destination\\DestinationManager $manager */\n\n$container-\u003eset(ReceiverLoaderInterface::class, function (ContainerInterface $container) {\n    return new ReceiverLoader(\n        $container,\n        [\n            'destination_name or connection_name' =\u003e function(ReceiverBuilder $builder) {\n                /** @var \\Bdf\\Queue\\Processor\\ProcessorInterface $myProcessor */\n                /** @var \\Bdf\\Queue\\Consumer\\ReceiverInterface $myReceiver */\n\n                // Register your unique handler for the destination or connection. \n                // all message will be handled by this handler.\n                $builder-\u003ehandler(MyHandler::class);\n                \n                // Or register your unique processor\n                $builder-\u003eprocessor($myProcessor);\n                \n                // Or register the job bearer resolver as processor. The procesor will resolve the job\n                // from the Message::$job attribute value.\n                $builder-\u003ejobProcessor();\n                \n                // Or register your own processor or handler by queue in case you consume a connection.\n                // By default the key of the map is the queue name. You can provide your own key provider \n                // with the second parameter.\n                $builder-\u003emapProcessor([\n                    'queue1' =\u003e $myProcessor,\n                    'queue2' =\u003e MyHandler::class,\n                ]);\n                \n                // Or register your final own receiver\n                $builder-\u003eoutlet($myReceiver);\n                \n                // Or register your own receiver in the stack\n                $builder-\u003eadd($myReceiver);\n                \n                // You can add more defined middlewares here\n                // $builder-\u003eretry(2);\n            }\n        ]\n    );\n});\n\n$receiver = $container-\u003eget(ReceiverLoaderInterface::class)-\u003eload('destination_name or connection_name')-\u003ebuild();\n\n$manager-\u003ecreate('queue://foo')-\u003econsumer($receiver)-\u003econsume(0);\n```\n\n#### Run the consumer in console\n\n```bash\n$ example/consumer.php \"connection name OR destination name\"\n\n```\n\n##### Create receiver extensions\n\nThe consumer use a stack of receivers to extend the reception of messages. \nSee the interface `Bdf\\Queue\\Consumer\\ReceiverInterface` and the trait `Bdf\\Queue\\Consumer\\DelegateHelper`.\n\n```PHP\n\u003c?php\nclass MyExtension implements \\Bdf\\Queue\\Consumer\\ReceiverInterface\n{\n    use \\Bdf\\Queue\\Consumer\\DelegateHelper;\n    \n    private $options;\n\n    /**\n     * MyExtension constructor.\n     */\n    public function __construct(\\Bdf\\Queue\\Consumer\\ReceiverInterface $delegate, array $options)\n    {\n        $this-\u003edelegate = $delegate;\n        $this-\u003eoptions = $options;\n    }\n    \n    /**\n     * {@inheritdoc}\n     */\n    public function receive($message, \\Bdf\\Queue\\Consumer\\ConsumerInterface $consumer): void\n    {\n        // Do something when receiving message\n        if ($message-\u003equeue() === 'foo') {\n            return;        \n        }\n\n        // Call the next receiver\n        $this-\u003edelegate-\u003ereceive($message, $consumer);\n    }\n}\n```\n\nYou can use the `Bdf\\Queue\\Consumer\\Receiver\\Builder\\ReceiverLoader::add()` to register your receiver in the stack\n```PHP\n\u003c?php\n$options = ['foo' =\u003e 'bar'];\n\n/** @var \\Bdf\\Queue\\Consumer\\Receiver\\Builder\\ReceiverBuilder $builder */\n$builder-\u003eadd(MyExtension::class, [$options]);\n```\n\n#### Customize the string payload\n\nThe class `Bdf\\Queue\\Serializer\\SerializerInterface` manage the payload content sent to the message broker.\nBy default metadata are added to the json as:\n- PHP Type: to help consumer to deserialize complex entities.\n- Message info: The attempt number for retry, The sending date, ...\n    \nA basic payload looks like:\n```json\n{\n  \"name\": \"Foo\",\n  \"data\": \"Hello World\",\n  \"date\": \"2019-12-23T16:02:03+01:00\"\n}\n```\n\nYou can customize the string with your own implementation of the serializer interface.\n\nTry the hello world example (configure the message broker in `example/config/connections.php`):\n```bash\n$ example/producer.php foo '{\"name\":\"Foo\", \"data\":\"Hello World\"}' --raw\n$ example/consumer.php foo\n```\n\n#### RPC client\n\n```PHP\n\u003c?php\n\nuse Bdf\\Queue\\Message\\InteractEnvelopeInterface;\nuse Bdf\\Queue\\Message\\Message;\n\nclass RpcReplyHandler\n{\n    public function doSomethingUseful(int $number, InteractEnvelopeInterface $envelope)\n    {\n        // Send bask: 1 x 2 to client\n        $envelope-\u003ereply($number * 2);\n\n        // Or retry in 10sec\n        $envelope-\u003eretry(10);\n    }\n}\n\n$message = Message::createFromJob(RpcReplyHandler::class.'@doSomethingUseful', 1, 'queue');\n$message-\u003esetConnection('foo');\n\n/** @var Bdf\\Queue\\Destination\\DestinationManager $manager */\n$promise = $manager-\u003esend($message);\n\n// Consume the foo connection\n\n// Receive data from the reply queue. If the header \"replyTo\" is not set, \n// the response will be sent to \"queue_reply\"\necho $promise-\u003eawait(500)-\u003edata(); // Display 2\n```\n\n\n#### Additionnal options for connection\n\n| Option               | Type     | Supports                 | Description                                                                                                                  |\n|----------------------|----------|--------------------------|------------------------------------------------------------------------------------------------------------------------------|\n| `driver`             | string   | all                      | The name of the driver to use. See driver name in support section.                                                           |\n| `vendor`             | string   | all                      | Second part of the protocol. Vendor is used by some driver that use internal drivers.                                        |\n| `queue`              | string   | all                      | The default queue of the connection used only if no queue has been set on the message. Destination should provide the queue. |\n| `host`               | string   | all                      | The host / ip to connect to message broker. Usually set to `localhost`.                                                      |\n| `port`               | int      | all                      | The port of the message broker. Usually set to the default port.                                                             |\n| `user`               | string   | all                      |                                                                                                                              |\n| `password`           | string   | all                      |                                                                                                                              |\n| `prefetch`           | int      | all                      | Load a number of message in memory. Faster for some broker that supports reservation                                         |\n| `serializer`         | string   | all                      | Load a serializer for this connection. Used only by driver that needs serializer.                                            |\n| `vhost`              | string   | amqp-lib                 | Default `/`.                                                                                                                 |\n| `group`              | string   | amqp-lib                 | Group use by topic to allows set of consumers on the same topic. Default `bdf`.                                              |\n| `sleep_duration`     | int      | amqp-lib                 | The internal sleep in milliseconds between two pop. Default `200`.                                                           |\n| `queue_flags`        | int      | amqp-lib                 | The flag for queue declaration. See AmqpDriver constants. Default `2` (`FLAG_QUEUE_DURABLE` value).                          |\n| `topic_flags`        | int      | amqp-lib                 | The flag for topic declaration. See AmqpDriver constants. Default `0` (`FLAG_NOPARAM` value).                                |\n| `consumer_flags`     | int      | amqp-lib                 | The flag for consumer. See AmqpDriver constants. Default `0` (`FLAG_NOPARAM` value).                                         |\n| `auto_declare`       | bool     | amqp-lib, redis, enqueue | Auto declare the queue when pushing or poping. Use queue setup command otherwise. Default `false`.                           |\n| `qos_prefetch_size`  | int      | amqp-lib                 | Prefetch optimisation. Default `0`.                                                                                          |\n| `qos_prefetch_count` | int      | amqp-lib                 | Prefetch optimisation. Default `1`.                                                                                          |\n| `qos_global`         | int      | amqp-lib                 | Prefetch optimisation. Default `false`.                                                                                      |\n| `table`              | string   | doctrine                 | The table name to use to store message. Default value `doctrine_queue`                                                       |\n| `ttr`                | int      | pheanstalk               | Time to run in seconds. Can also be defined in message header. Default `60`.                                                 |\n| `client-timeout`     | int      | pheanstalk, gearman      | Timeout of client in milliseconds. Disable by default.                                                                       |\n| `commitAsync`        | bool     | rdkafka                  | Enable asynchrone ack. Default `false`.                                                                                      |\n| `offset`             | int      | rdkafka                  | Position to start consumer. Default `null`.                                                                                  |\n| `partition`          | int      | rdkafka                  | Partition to for the consumer, see kafka constant. Default `-1` (`RD_KAFKA_PARTITION_UA` value).                             |\n| `global`             | array    | rdkafka                  | Kafka config for global settings.                                                                                            |\n| `producer`           | array    | rdkafka                  | Kafka config for producer.                                                                                                   |\n| `consumer`           | array    | rdkafka                  | Kafka config for the consume                                                                                                 |\n| `poll_timeout`       | int      | rdkafka                  | The timeout for the poll method in milliseconds.                                                                             |\n| `flush_timeout`      | int      | rdkafka                  | The timeout for the flush method in milliseconds.                                                                            |\n| `dr_msg_cb`          | callable | rdkafka                  | Delivery report callback.                                                                                                    |\n| `error_cb`           | callable | rdkafka                  | Error callback.                                                                                                              |\n| `rebalance_cb`       | callable | rdkafka                  | Called after consumer group has been rebalanced.                                                                             |\n| `stats_cb`           | callable | rdkafka                  | Statistics callback.                                                                                                         |\n| `partitioner`        | string   | rdkafka                  | Kafka partitioner for topic settings.                                                                                        |\n| `group`              | string   | rdkafka                  | Group use by topic to allows set of consumers on the same topic. Default `\"2\"`.                                              |\n| `timeout`            | int      | redis                    | The connection timeout in seconds. Default `0`.                                                                              |\n| `prefix`             | string   | redis                    | The key prefix. Default `queues:`.                                                                                           |\n\nNote:\n* Format of a valid DSN: {driver}+{vendor}://{user}:{password}@{host}:{port}/{queue}?{option}=value\n* See https://github.com/confluentinc/librdkafka/blob/master/CONFIGURATION.md for more kafka options.\n\n#### Additionnal options for message\n\n| Option              | Type        | Supports                       | Description  |\n|---------------------|-------------|--------------------------------|--------------|\n| `flags`             | int         | amqp-lib                       | The flags for message. See driver constants. |\n| `priority`          | int         | pheanstalk                     | Priority message. Default `1024`. |\n| `ttr`               | int         | pheanstalk                     | Time to run in seconds. Default `60`. |\n| `key`               | string      | rdkafka                        |  |\n| `partition`         | int         | rdkafka                        | The number of the partition. |\n\n\n### Serialization\n\n#### Benchmarks\n\nsimple job / closure job\n\n|Serializer       | Serializer     | +Compress       | Bdf JSON      | +Compress     | Bdf binary    | \n|-----------------|----------------|-----------------|---------------|---------------|---------------|\n|Size             | 141 / 377      | 105 / 244       | 109 / 407     | 76 / 247      | 98 / 355      |\n|Serialize time   | 0.0014 / 6.8   | 0.016 / 7       | 0.011 / 7     | 0.026 / 7     | 0.011 / 7     |\n|Unserialize time | 0.007 / 0.0025 | 0.0082 / 0.0068 | 0.024 / 0.015 | 0.024 / 0.019 | 0.019 / 0.011 |\n\n#### Analysis\n\n- For the best execution time, regardless of size, use the default `Serializer`\n- For the smaller size, regardless of time, use `BdfSerializer` with `CompressedSerializer`\n- For the best compromise, use `Serializer` with `CompressedSerializer`\n    - Always smaller than pure `BdfSerializer` (JSON or Binary)\n    - Faster on **unserialize**, slightly slower on **serialize**\n    - Around **twice faster** than compressed bdf, but **only ~40% larger** on simple job\n    \n\n## License\n\nDistributed under the terms of the MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fb2pweb%2Fbdf-queue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fb2pweb%2Fbdf-queue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fb2pweb%2Fbdf-queue/lists"}