Problem/Motivation

When a path is processed by the tome generator, any files (JS, CSS, images) attached are copies from their original location into the staging area for the preview site.
For a non trivial node (e.g. a page with a complex react application) this could result in one path requiring 100 files to be copied.
On a distributed file system like EFS, copying 100 files as well as any other processing for that path may not complete in the allowed timeout for a single request

Steps to reproduce

Configure local host to have a 60s timeout
Edit tome's static generator class's copyPath method to add a 300ms sleep after each file copy to emulate latency seen in a distributed file system
Attempt to generate a preview for a piece of content with a complex FE component/ React app
Experience timeout

Proposed resolution

We already sub-class tome's static generator and have an implementation of copyPaths that tracks copied files.
Instead of calling the parent in this method, push the file paths to the build.
Have the deploy process deploy them from the original file instead of a copied version

Remaining tasks

User interface changes

API changes

Data model changes

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

larowlan created an issue. See original summary.

dpi’s picture

Trying to figure out the big picture here.

As far as I can tell its not quite as simple as moving body of the copy operation to a new queue, as the caller relies on the copied file, and recursively looks for more resources within the copied file.

Perhaps \Drupal\preview_site\Plugin\PreviewSite\Generate\TomeGenerator::generateBuildForPath should be split at the $remaining_assets = $this->static->exportPaths($invoke_paths); point.

Where \Drupal\tome_static\StaticGenerator::exportPaths becomes a variable/dynamic size batch recursively copying files.

larowlan’s picture

Looks good, but getting an odd bot failure

acbramley’s picture

Status: Active » Needs work

Testing this locally it's deleting css and js files that it copies over.

acbramley’s picture

Status: Needs work » Needs review

We've been running this in prod for some time and it seems to be working well.

acbramley’s picture

Status: Needs review » Needs work

This is actually causing massive issues with #3230078: Add support for Javascript modules - if a page contains a javascript file that imports chunks this patch causes some sort of recursion on those chunks adding thousands of files to the export and taking a long time to complete (over an hour up from 5 minutes).

EDIT: The chunked JS files also don't make it to S3

larowlan’s picture

Status: Needs work » Needs review
StatusFileSize
new24.3 KB

First a re-roll

Status: Needs review » Needs work

The last submitted patch, 8: 3271913-8.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

larowlan’s picture

Title: Move file copy processing to a queue to prevent timeouts » Don't bother file file copies during build, keep them on the build and deploy from the original file
Issue summary: View changes
Status: Needs work » Needs review
larowlan’s picture

StatusFileSize
new20.71 KB

New approach, no interdiff as its a do-over

Status: Needs review » Needs work

The last submitted patch, 11: 3271913-2.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

larowlan’s picture

Title: Don't bother file file copies during build, keep them on the build and deploy from the original file » Don't bother with file copies during build, keep them on the build and deploy from the original file
Status: Needs work » Needs review
larowlan’s picture

Title: Don't bother with file copies during build, keep them on the build and deploy from the original file » Don't bother with file copies during build, keep file paths on the build and deploy from the original file
larowlan’s picture

StatusFileSize
new4.16 KB
new21.65 KB

Allow for subdirectory on test-bot

Status: Needs review » Needs work

The last submitted patch, 15: 3271913-10.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

larowlan’s picture

Status: Needs work » Needs review
StatusFileSize
new1.13 KB
new21.42 KB

Take two

acbramley’s picture

--- a/modules/preview_site_s3/src/Plugin/PreviewSite/Deploy/S3.php
+++ b/modules/preview_site_s3/src/Plugin/PreviewSite/Deploy/S3.php

@@ -269,4 +269,32 @@ class S3 extends DeployPluginBase implements ContainerFactoryPluginInterface {
+  public function deployFilePath(PreviewSiteBuildInterface $build, string $path): void {

This is almost identical to deployArtifact

Can we reafctor that so it calls this with FileHelper::getFilePathWithoutSchema($file, $build) as the path?

Otherwise looking pretty good, great idea!

larowlan’s picture

Can we reafctor that so it calls this with FileHelper::getFilePathWithoutSchema($file, $build) as the path?

I considered it, but was on the fence, but having another vote for doing it helps sway me towards it. Will do!

larowlan’s picture

StatusFileSize
new11.65 KB
new31.03 KB

Made that change and fixed some PHPCS while I was at it

mortim07’s picture

I mentioned this to @larowlan, but this has also solved OOM issues with the preview site build form - during validation it was validating the entity reference for all artifacts.

larowlan’s picture

Status: Needs review » Fixed

Cutting a new release with this

  • larowlan committed b292dcc6 on 1.x
    Issue #3271913 by larowlan, dpi, acbramley, mortim07: Don't bother with...
kamil_lw’s picture

Status: Fixed » Active

Hello,

I'm reopening this issue, because I'm experiencing a PHP Fatal Error.

Here's a part of the stack trace:

 Error: Call to undefined method Drupal\preview_site\Generate\TomeStaticExtension::getJavascriptModules() in /opt/drupal/web/modules/contrib/preview_site/src/Generate/TomeStaticExtension.php:185 Stack trace: 
#0 /opt/drupal/web/modules/contrib/preview_site/src/Plugin/PreviewSite/Generate/TomeGenerator.php(207): Drupal\preview_site\Generate\TomeStaticExtension->exportPaths(Array) 
#1 /opt/drupal/web/modules/contrib/preview_site/src/Plugin/PreviewSite/Generate/TomeGenerator.php(129): Drupal\preview_site\Plugin\PreviewSite\Generate\TomeGenerator->generateBuildForPath(Object(Drupal\preview_site\Entity\PreviewSiteBuild), '_entity:node:en...', 'http://default/...', Object(Drupal\Core\Queue\DatabaseQueue)) 
#2 /opt/drupal/web/modules/contrib/preview_site/src/Plugin/QueueWorker/Generate.php(115): Drupal\preview_site\Plugin\PreviewSite\Generate\TomeGenerator->generateBuildForItem(Object(Drupal\preview_site\Entity\PreviewSiteBuild), Object(Drupal\dynamic_entity_reference\Plugin\Field\FieldType\DynamicEntityReferenceItem), 'http://default/...', Object(Drupal\Core\Queue\DatabaseQueue)) 
#3 /opt/drupal/web/modules/contrib/preview_site/src/PreviewSiteBuilder.php(180): Drupal\preview_site\Plugin\QueueWorker\Generate->processItem(0) 
#4 /opt/drupal/web/modules/contrib/preview_site/src/PreviewSiteBuilder.php(120): Drupal\preview_site\PreviewSiteBuilder->processQueueItem('preview_site_ge...') 
#5 /opt/drupal/web/modules/contrib/preview_site/src/PreviewSiteBuilder.php(242): Drupal\preview_site\PreviewSiteBuilder->processSiteGeneration(Object(Drupal\preview_site\Entity\PreviewSiteBuild)) 
#6 /opt/drupal/packages/languagewire_tmgmt_connector/src/Adapter/PreviewSite/PreviewSiteBuilder.php(66): Drupal\preview_site\PreviewSiteBuilder::operationProcessGenerate(303, Array)
(...)

I've taken a look at the preview_site module source code, and I indeed can find the "getJavascriptModules()" method definition nowhere in there.

This issue was introduced in the release 1.1.5 of the module.

PS. This is my first time adding a comment in Drupal's issue tracker. Please forgive me if I should have opened a new issue instead.

acbramley’s picture

You're right, that function is provided by https://www.drupal.org/project/tome/issues/3230078

I'm surprised tests are passing...

mortim07’s picture

@acbramley There isn't test coverage for it. Do we remove the patch for now and roll a new release until the dependency is merged in?

  • acbramley committed 1068f906 on 1.x
    Revert "Issue #3271913 by larowlan, dpi, acbramley, mortim07: Don't...
acbramley’s picture

Status: Active » Needs work

I've reverted the commit and published 1.1.6

mortim07’s picture

Great @acbramley!

larowlan’s picture

Let's try and push that one forward then

larowlan’s picture

Status: Needs work » Needs review
StatusFileSize
new783 bytes
new31.63 KB

The tome issue is fixed/released so here's a new patch with a minimum requirement on that version of tome

acbramley’s picture

Status: Needs review » Reviewed & tested by the community

Awesome! RTBC assuming green :)

  • larowlan committed 14010b07 on 1.x
    Issue #3271913 by larowlan, dpi, acbramley, mortim07, kamil_lw: Don't...
larowlan’s picture

Status: Reviewed & tested by the community » Fixed

Ran the tests locally, as something not right with drupalci, the folder is missing 🤔

phpunit -c app/core app/modules/preview_site --stop-on-failure
⏳️ Bootstrapped tests in 0 seconds.
🐘 PHP Version 8.1.16.
💧 Drupal Version 9.5.8-dev.
🗄️  Database engine mysql.
PHPUnit 9.6.6 by Sebastian Bergmann and contributors.

Testing /data/app/modules/preview_site
................................................................. 65 / 66 ( 98%)
.                                                                 66 / 66 (100%)

Time: 03:17.707, Memory: 18.00 MB

OK (66 tests, 1615 assertions)

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.