Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

assets:install should keep ctime/mtime when in copy mode #54327

Closed
zerkms opened this issue Mar 19, 2024 · 9 comments
Closed

assets:install should keep ctime/mtime when in copy mode #54327

zerkms opened this issue Mar 19, 2024 · 9 comments

Comments

@zerkms
Copy link
Contributor

zerkms commented Mar 19, 2024

Description

Creation/last modification time of the web assets is used by web servers in the Last-Modified header.

Hence if you have multiple instances of the application which had their assets:install run at different times - depending on what instance you hit - you may receive different values which would confuse the web server (as Last-Modified must match the If-Modified-Since exactly) and it would return http 200 and entire asset, instead of http 304.

Example

none

@smnandre
Copy link
Contributor

@zerkms: How do you retrieve the "ctime/mtime" values? As far as I know, files are timestamped when you pull them from Git, and they don't retain their original timestamps. Wouldn't this result in differences depending on the build time?

Regarding caching, an 'immutable' cache header + long duration represents imho a better approach for caching static assets than LastModified (only), as they are versioned and never change afterwards. And i'm not sure i'd want a deployment script to mess with files metadata, this could have other side effects.

Another solution could be to use hash-based ETags, removing the need for timestamps ?

Some links about immutable/best practices :

@zerkms
Copy link
Contributor Author

zerkms commented Mar 19, 2024

How do you retrieve the "ctime/mtime" values?

whatever it is currently in the filesystem.

Wouldn't this result in differences depending on the build time?

It's fine, at least it will be the same everywhere.

And i'm not sure i'd want a deployment script to mess with files metadata, this could have other side effects.

This is controversial: deployment scripts deal with files - be it files contents, names, or metadata - I don't see any difference.

Some links about immutable/best practices

I know how caching in http works and how to workaround the problem. My suggestion is to not create problems in the very first place so that you didn't need to bring even more configuration to solve it.

Nonetheless, I suggest to NOT discuss "the best practices" of how it should be done otherwise. My suggestion is - would the symfony team consider it, or not?

@smnandre
Copy link
Contributor

I apologize if my message caused any offense; that was never my intention. I have recently dedicated some time to researching this topic and shared those bookmarks with the sole hope that they might be of interest to anyone reading this issue.

@nicolas-grekas
Copy link
Member

IMHO, this concern doesn't belong to this command. We don't have mtime to keep track of.
Instead, I'd suggest syncing mtimes with the last update of each files in the git history.

This does it (using concurrency to be a bit faster than a simple loop):

git ls-tree -r --name-only HEAD | xargs -I {} -P $(nproc) bash -c '
filename="$1"
commitDate=$(git log -1 --format="%ai" -- "$filename")
if [ -n "$commitDate" ]; then
    touch -d "$commitDate" "$filename"
fi
' _ {}

@zerkms
Copy link
Contributor Author

zerkms commented Mar 20, 2024

We don't have mtime to keep track of.

How do you know that? It's not symfony's domain of responsibility to know how and where the source code retrieved from :-)

Anyway, assets:install keeps the files contents, their names. Any reason to not keep metadata? Possibly through another option?

@nicolas-grekas
Copy link
Member

Why would we when I just gave a nice solution?

@zerkms
Copy link
Contributor Author

zerkms commented Mar 20, 2024

a nice solution

it's a workaround, not a solution: you could have copied the assets with a bash scripts too, but instead there is command for that.

So, why would the command retain names, and content, but drop metadata? Any particular reason to NOT keep metadata?

@xabbuh
Copy link
Member

xabbuh commented Mar 21, 2024

The root cause is that in Filesystem::mirror() we use stream_copy_to_stream() under the hood. I opened #54362 to keep the modification time in the same way that we preserve file permissions.

@fabpot fabpot closed this as completed Mar 21, 2024
fabpot added a commit that referenced this issue Mar 21, 2024
…oring directories (xabbuh)

This PR was merged into the 5.4 branch.

Discussion
----------

[Filesystem] preserve the file modification time when mirroring directories

| Q             | A
| ------------- | ---
| Branch?       | 5.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Issues        | Fix #54327
| License       | MIT

Commits
-------

d232026 preserve the file modification time when mirroring directories
@nicolas-grekas
Copy link
Member

Ah, thanks for digging this @xabbuh!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants