@@ -22,6 +22,7 @@ import (
22
22
"os"
23
23
"path"
24
24
"path/filepath"
25
+ "sync"
25
26
)
26
27
27
28
// Loader is a minimal interface required for loading templates.
@@ -42,7 +43,6 @@ import (
42
43
// `/bar.html.jet` and `/bar.jet.html` (in that order). To avoid unneccessary lookups, use the full file name in your templates (so the first lookup
43
44
// is always a hit, or override this list of extensions using Set.SetExtensions().
44
45
type Loader interface {
45
-
46
46
// Exists returns whether or not a template exists under the requested path.
47
47
Exists (templatePath string ) bool
48
48
@@ -84,10 +84,11 @@ func (l *OSFileSystemLoader) Open(templatePath string) (io.ReadCloser, error) {
84
84
}
85
85
86
86
// InMemLoader is a simple in-memory loader storing template contents in a simple map.
87
- // It is not safe for concurrent use.
88
87
// InMemLoader normalizes paths passed to its methods by converting any input path to a slash-delimited path,
89
88
// turning it into an absolute path by prepending a "/" if neccessary, and cleaning it (see path.Clean()).
89
+ // It is safe for concurrent use.
90
90
type InMemLoader struct {
91
+ lock sync.RWMutex
91
92
files map [string ][]byte
92
93
}
93
94
@@ -109,6 +110,8 @@ func (l *InMemLoader) normalize(templatePath string) string {
109
110
// Open returns a template's contents, or an error if no template was added under this path using Set().
110
111
func (l * InMemLoader ) Open (templatePath string ) (io.ReadCloser , error ) {
111
112
templatePath = l .normalize (templatePath )
113
+ l .lock .RLock ()
114
+ defer l .lock .RUnlock ()
112
115
f , ok := l .files [templatePath ]
113
116
if ! ok {
114
117
return nil , fmt .Errorf ("%s does not exist" , templatePath )
@@ -120,18 +123,24 @@ func (l *InMemLoader) Open(templatePath string) (io.ReadCloser, error) {
120
123
// Exists returns whether or not a template is indexed under this path.
121
124
func (l * InMemLoader ) Exists (templatePath string ) bool {
122
125
templatePath = l .normalize (templatePath )
126
+ l .lock .RLock ()
127
+ defer l .lock .RUnlock ()
123
128
_ , ok := l .files [templatePath ]
124
129
return ok
125
130
}
126
131
127
132
// Set adds a template to the loader.
128
133
func (l * InMemLoader ) Set (templatePath , contents string ) {
129
134
templatePath = l .normalize (templatePath )
135
+ l .lock .Lock ()
136
+ defer l .lock .Unlock ()
130
137
l .files [templatePath ] = []byte (contents )
131
138
}
132
139
133
140
// Delete removes whatever contents are stored under the given path.
134
141
func (l * InMemLoader ) Delete (templatePath string ) {
135
142
templatePath = l .normalize (templatePath )
143
+ l .lock .Lock ()
144
+ defer l .lock .Unlock ()
136
145
delete (l .files , templatePath )
137
146
}
0 commit comments