View Issue Details

This bug affects 1 person(s).
 8
IDProjectCategoryView StatusLast Update
20105Feature requestsOtherpublic2025-05-26 08:54
Reporter2BITS_PL Assigned Toc_schmitz  
PrioritynoneSeverity@50@ 
Status assignedResolutionopen 
Summary20105: AssetManager: inconsistent hashes due to filemtime in distributed deployments
Description

In distributed setups (e.g. behind a load balancer or using blue-green deployments), we're experiencing issues with inconsistent asset hashes caused by the use of filemtime() in the AssetManager.

The problem occurs because the generatePath() method uses filemtime() to build the asset directory hash. On multiple nodes, file modification times may differ despite identical content, leading to mismatched hashes. This causes 404 errors or missing assets when users switch between nodes.

Sticky sessions can partially mitigate this in load-balanced environments, but blue-green deployments still cause hash mismatches when switching traffic from one environment to another.

We have a few questions:

  1. What was the rationale behind using filemtime() as part of the hash?
  2. Since the asset versioning already includes globalAssetsVersion (which is automatically incremented when clearing assets via the admin panel), is filemtime() still necessary?
  3. If we override the behavior to exclude filemtime(), what are the risks?

This behavior makes it hard to maintain reliable deployments in production environments.

TagsNo tags attached.
Bug heat8
Story point estimate
Users affected %

Users monitoring this issue

There are no users monitoring this issue.

Activities

DenisChenu

DenisChenu

2025-05-15 17:31

developer   ~82677

What was the rationale behind using filemtime() as part of the hash?

To be sure to have a new file when you update it.
Included in Yii

Since the asset versioning already includes globalAssetsVersion (which is automatically incremented when clearing assets via the admin panel), is filemtime() still necessary?

Yes : when you update a file : it was never reset except if you click on the button.

If we override the behavior to exclude filemtime(), what are the risks?

On a fixed environment : none

DenisChenu

DenisChenu

2025-05-15 17:33

developer   ~82678

Yii : https://github.com/LimeSurvey/LimeSurvey/blob/a7aaf89092a36e98b045344730315144f425cec0/vendor/yiisoft/yii/framework/web/CAssetManager.php#L328

2BITS_PL

2BITS_PL

2025-05-16 09:30

reporter   ~82685

What about changes in theme extension files (like CSS or JS in a theme)?

If we update those files directly (e.g. via deployment), but don't clear the asset cache or increment globalAssetsVersion, wouldn't filemtime() be necessary in that case?
I saw that LimeSurvey has an AssetVersion table in the database which stores extension paths and their versions, but it seems the version is only incremented when clicking "reset" — not when a file is modified.

DenisChenu

DenisChenu

2025-05-16 09:58

developer   ~82686

I saw that LimeSurvey has an AssetVersion table in the database which stores extension

Used (for example) when save theme. Can be updated by plugin, maybe must be when update plugin (after uploadintg).

I understand your POV : but in my opinion: it must be a new feature : disable mtime checking in asset. Strangely: it was not in YII …

2BITS_PL

2BITS_PL

2025-05-16 11:33

reporter   ~82687

This option would be especially useful in stable environments.

filemtime() is useful in development, but in production we can manage versioning via the admin panel (asset clear) or by setting a new 'customassetversionnumber' in config.

Disabling filemtime() would help in distributed systems, where file timestamps can differ across nodes.
We know that we can override the assetManager in the configuration by setting a custom class that extends CAssetManager — just like LimeSurvey does with LSYii_AssetManager, removing mtime. However, after each Limesurvey update, we would have to remember to reapply it.

DenisChenu

DenisChenu

2025-05-16 12:16

developer   ~82688

Last edited: 2025-05-16 12:16

We know that we can override the assetManager in the configuration by setting a custom class that extends CAssetManager — just like LimeSurvey does with LSYii_AssetManager, removing mtime.

:+1:

However, after each Limesurvey update, we would have to remember to reapply it.

Maybe :
1 put your class out of LimeSurvey directory
2 Load it in your config.php

  1. In yoiur config.php : set your own assetManager https://github.com/LimeSurvey/LimeSurvey/blob/a7aaf89092a36e98b045344730315144f425cec0/application/config/internal.php#L148

Unsure, maybe it's possible to do it in a plugin.

2BITS_PL

2BITS_PL

2025-05-16 12:53

reporter   ~82689

Exactly, that’s what we do now.

However, we need to document this as a custom change in LimeSurvey’s change log or upgrade notes to make sure we don’t forget it in the future—especially when upgrading major LimeSurvey versions.

I’m not sure if it can be done as a plugin.

mfavetti

mfavetti

2025-05-20 03:20

developer   ~82712

I mitigate this by having shared storage for tmp/assets so nodes in the application layer can serve assets generated by all nodes

2BITS_PL

2BITS_PL

2025-05-20 12:21

reporter   ~82715

Thanks for the suggestion!

The issue is that filemtime() is called on the original asset source files (e.g. from plugins or application modules), not just on the files already copied to tmp/assets. So for shared tmp/assets to work reliably, we’d also need to ensure shared access to all asset sources.

This would require either splitting the application into separately mountable parts or placing the entire application on shared storage, while keeping only configuration local to each node. That’s not optimal for us — especially since the shared disk would also need to be accessible within the load balancer setup.

In practice, we’re back to the original problem: filemtime() would have to be identical across all nodes behind the load balancer for all shared asset sources — which is difficult to guarantee.

That’s why we’re asking if there could be a solution that allows disabling filemtime checks in production environments.

c_schmitz

c_schmitz

2025-05-20 15:49

administrator   ~82723

Simplest solution would probably that the load balancer that syncs files also syncs mtimes.

2BITS_PL

2BITS_PL

2025-05-20 17:00

reporter   ~82725

Syncing filemtime across nodes is infeasible in our distributed setup.

We use blue-green deployments behind a load balancer with a split frontend/backend architecture. This means 4 active nodes per deployment, 8 with blue-green. Keeping identical filemtime on all nodes is operationally impractical.

CI/CD pipelines do not preserve modification times, and adding mtime synchronization would overcomplicate deployment.
It is simpler and safer to remove filemtime from the asset hash calculation.

We request an option to disable filemtime usage in hash generation, enabled by default but configurable for setups like ours, where asset reloads always follow customAssetVersionNumber increments.

mfavetti

mfavetti

2025-05-20 23:13

developer   ~82726

@2BITS_PL How do you handle uploads?

mfavetti

mfavetti

2025-05-23 23:01

developer   ~82753

Maybe tie the use of modification time to debug level? (Don't use for 0, use for >=1)
Or add configuration option to use for development similar to "force_xmlsettings_for_survey_rendering"?

DenisChenu

DenisChenu

2025-05-26 08:45

developer   ~82758

@c_schmitz : move it to feature request ?

Issue History

Date Modified Username Field Change
2025-05-15 13:27 2BITS_PL New Issue
2025-05-15 17:31 DenisChenu Note Added: 82677
2025-05-15 17:31 DenisChenu Bug heat 0 => 2
2025-05-15 17:33 DenisChenu Note Added: 82678
2025-05-16 09:30 2BITS_PL Note Added: 82685
2025-05-16 09:30 2BITS_PL Bug heat 2 => 4
2025-05-16 09:58 DenisChenu Note Added: 82686
2025-05-16 11:33 2BITS_PL Note Added: 82687
2025-05-16 12:16 DenisChenu Note Added: 82688
2025-05-16 12:16 DenisChenu Note Edited: 82688
2025-05-16 12:53 2BITS_PL Note Added: 82689
2025-05-20 03:20 mfavetti Note Added: 82712
2025-05-20 03:20 mfavetti Bug heat 4 => 6
2025-05-20 12:21 2BITS_PL Note Added: 82715
2025-05-20 15:49 c_schmitz Note Added: 82723
2025-05-20 15:49 c_schmitz Bug heat 6 => 8
2025-05-20 17:00 2BITS_PL Note Added: 82725
2025-05-20 23:13 mfavetti Note Added: 82726
2025-05-23 15:08 tibor.pacalat Assigned To => c_schmitz
2025-05-23 15:08 tibor.pacalat Status new => assigned
2025-05-23 23:01 mfavetti Note Added: 82753
2025-05-26 08:45 DenisChenu Note Added: 82758
2025-05-26 08:54 c_schmitz Project Bug reports => Feature requests
2025-05-26 08:54 c_schmitz Category Assets => Other