【问题标题】:Deleting files in temporary directory generated by laravel-snappy删除 laravel-snappy 生成的临时目录中的文件
【发布时间】:2017-11-10 13:03:06
【问题描述】:

我们正在使用这个库 laravel-snappy 在队列中生成 PDF。

该库旨在在执行脚本后删除所有 tmp 文件。这是由于Knp\Snappy\AbstractGenerator 类中的以下代码:

public function __destruct()
{
    $this->removeTemporaryFiles();
}

参考 - https://github.com/KnpLabs/snappy/blob/master/src/Knp/Snappy/AbstractGenerator.php#L57

当我们在队列作业和 Laravel 中使用它时,一旦 queue:work 命令启动,它将继续运行,直到手动停止或关闭终端。

所以要清理 tmp 文件,我每次都必须重新启动队列工作程序。

有没有其他选择?

注意 - laravel-snappy 的包装器内的类 Knp\Snappy\AbstractGenerator 的实例是 protected。所以我不能直接调用它的方法。

参考 - https://github.com/barryvdh/laravel-snappy/blob/master/src/PdfWrapper.php#L20

【问题讨论】:

  • 这个函数有一个循环检查php配置可能是最大执行时间的问题尝试删除少量文件第二件事检查你的文件夹权限。
  • 您希望队列工作者每天自动启动并删除您的临时文件?即使您可以使用 setTemporaryFolder 更改临时文件夹的位置,也请明确说明您真正想要的内容,为什么您会担心这个小东西。

标签: php laravel laravel-snappy


【解决方案1】:

参考:- Read this doc

主管配置

Supervisor 是 Linux 操作系统的进程监视器,如果 queue:listen 或 queue:work 命令失败,它将自动重新启动它们。要在 Ubuntu 上安装 Supervisor,您可以使用以下命令:

sudo apt-get install supervisor

Supervisor 配置文件通常存储在 /etc/supervisor/conf.d 目录中。在此目录中,您可以创建任意数量的配置文件,指示主管应如何监控您的进程。例如,让我们创建一个 laravel-worker.conf 文件来启动和监控一个 queue:work 进程:

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /home/forge/app.com/artisan queue:work sqs --sleep=3 --tries=3 --daemon
autostart=true
autorestart=true
user=forge
numprocs=8
redirect_stderr=true
stdout_logfile=/home/forge/app.com/worker.log

在本例中,numprocs 指令将指示 Supervisor 运行 8 个 queue:work 进程并监控所有进程,如果它们失败则自动重新启动它们。当然,您应该更改命令指令的 queue:work sqs 部分以反映您选择的队列驱动程序。

创建配置文件后,您可以使用以下命令更新 Supervisor 配置并启动进程:

sudo supervisorctl reread

sudo supervisorctl update

sudo supervisorctl start laravel-worker:*

【讨论】:

  • 抱歉,您没有收到问题。我会重新措辞并提供更多细节。
【解决方案2】:

我不使用该库,但据我了解,有一个生成器类可用于生成 PDF。

一旦这个类被释放,它会删除所有的 tmp 文件,因为析构函数被调用了。

有一个实现的参考

Knp\Snappy\AbstractGenerator

点赞$generator = new SomeConcreteGenerator();

它似乎由包装器持有,因此您不能将其设置为 null。

你可能会得到一个包装器,它通过

来保存具体的生成器
$pdf = App::make('snappy.pdf.wrapper');

因此,您可以通过$pdf = null 释放包装器,然后创建一个新包装器。您必须在创建 1000 个 Pdf 之后执行此操作。

这种方法的问题是,服务通过$this->app->singleton(...) 绑定到DIC 作为单例。 See source code

所以它保留了我们想要释放的引用。

尝试通过将源代码修改为 $this->app->bind(...) 而不是 $this->app->singleton(...) 来进行常规绑定。

See here on binding.

(您不应该调用__destruct(),因为您基本上会破坏 DIC 拥有的对象。)

【讨论】:

  • $pdf = null 没有帮助,但是当我执行$pdf->__destruct() 之类的操作时,它会调用 Knp\Snappy\AbstractGenerator 类的析构函数并删除所有 tmp 文件。我不是 100% 相信这个解决方案,所以我会给图书馆提供一些替代方案的 PR。如果您有任何其他想法,请告诉我。
  • 是的,你在__destruct()这件事上是对的。会避免使用它。
  • 你尝试过常规绑定而不是单例吗?
猜你喜欢
  • 2019-05-15
  • 1970-01-01
  • 1970-01-01
  • 2014-04-06
  • 2014-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-27
相关资源
最近更新 更多