Skip to content

Optimizing export #347

@kirya-dev

Description

@kirya-dev

For export large data need call flush() in StreamedResponse.
its allow clear buffer and not use extra memory.
Todo as feature of framework?

My solution:

# config/services.yml
services:
    app.export.writer.csv:
        class: App\Writer\FlushWriterDecorator
        decorates: sonata.exporter.writer.csv

    app.export.writer.json:
        class: App\Writer\FlushWriterDecorator
        decorates: sonata.exporter.writer.json

    app.export.writer.xml:
        class: App\Writer\FlushWriterDecorator
        decorates: sonata.exporter.writer.xml

    app.export.writer.xls:
        class: App\Writer\FlushWriterDecorator
        decorates: sonata.exporter.writer.xls
<?php
declare(strict_types=1);

namespace App\Writer;

use Sonata\Exporter\Writer\TypedWriterInterface;

class FlushWriterDecorator implements TypedWriterInterface
{
    private const FLUSH_EVERY = 1000;

    private int $position;
    private TypedWriterInterface $writer;

    public function __construct(TypedWriterInterface $writer)
    {
        $this->writer = $writer;
    }

    public function open(): void
    {
        $this->writer->open();

        $this->position = 0;
    }

    public function write(array $data): void
    {
        $this->writer->write($data);

        $this->position++;
        if (0 === ($this->position % self::FLUSH_EVERY)) {
            flush();
        }
    }

    public function close(): void
    {
        $this->writer->close();
    }

    public function getDefaultMimeType(): string
    {
        return $this->writer->getDefaultMimeType();
    }

    public function getFormat(): string
    {
        return $this->writer->getFormat();
    }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions