vapor / template-kit

📄 Easy-to-use foundation for building powerful templating languages in Swift.
MIT License
46 stars 17 forks source link

Leaf template caching with non-unique keys #25

Closed foscomputerservices closed 6 years ago

foscomputerservices commented 6 years ago

I'm struggling with the wrong leaf template being rendered in production (not in development). I'm almost 100% sure that this is a caching problem as if I turn caching off all works as expected.

In digging into TemplateRenderer, I find the following:

public func render(template: Data, _ context: TemplateData, file: String = "template") -> Future<View> {
    return Future.flatMap(on: container) {
        let hash = template.hashValue
        let ast: [TemplateSyntax]
        if let cached = self.astCache?.storage[hash] {
            ast = cached
        } else {
            let scanner = TemplateByteScanner(data: template, file: file)
            ast = try self.parser.parse(scanner: scanner)
            self.astCache?.storage[hash] = ast
        }
        ...

Can hashValue on Data really be used as a unique key? I seem to be getting a collision in two of my templates. In the attached debugger autos windows that is stopped at the "if let cached = ..." line above, you'll see that the hash is the same value for both template files, however, the template files are drastically different.

screen shot 2018-06-21 at 12 12 47 pm screen shot 2018-06-21 at 12 13 37 pm

(Please note: I migrated this issue from Leaf #114 as the issue really is with template-kit and not Leaf -- I apologize for incorrectly locating the issue originally)

joeblau commented 6 years ago

TemplateData needs to conform to the Hashable protocol and the corresponding function needs to be implemented.

tanner0101 commented 6 years ago

This has been fixed in #31. The file path is now used. Templates that don't have a path are no longer cached. Thanks!