9
9
"net/http"
10
10
"os"
11
11
"path"
12
+ "strconv"
12
13
"strings"
13
14
"time"
14
15
@@ -17,6 +18,7 @@ import (
17
18
"github.com/go-chi/chi/v5"
18
19
"github.com/go-chi/cors"
19
20
"github.com/go-chi/render"
21
+ lru "github.com/hashicorp/golang-lru/v2"
20
22
bf "github.com/ipfs/boxo/files"
21
23
bp "github.com/ipfs/boxo/path"
22
24
"github.com/ipfs/go-cid"
@@ -82,9 +84,15 @@ func readUnixFile(ctx context.Context, rpc *kr.HttpApi, path string) (bf.File, e
82
84
return file , nil
83
85
}
84
86
85
- func getSepFromId (ctx context.Context , kubo * kr.HttpApi , id string ) (Sep , error ) {
87
+ func getSepFromId (ctx context.Context , kubo * kr.HttpApi , cache * lru. Cache [ string , Sep ], id string ) (Sep , error ) {
86
88
87
89
var sep Sep
90
+ // check if id is in cache
91
+ if v , ok := cache .Get (id ); ok {
92
+ log .Printf ("Using cache for id: %s" , id )
93
+ return v , nil
94
+ }
95
+
88
96
// collect the sep standard to retrieve content
89
97
standard , err := readUnixFile (ctx , kubo , path .Join ("/ipfs/" , id ))
90
98
if err != nil {
@@ -101,13 +109,14 @@ func getSepFromId(ctx context.Context, kubo *kr.HttpApi, id string) (Sep, error)
101
109
return Sep {}, err
102
110
}
103
111
112
+ cache .Add (id , sep )
104
113
return sep , nil
105
114
106
115
}
107
116
108
117
// TODO refactor all these to modules
109
118
110
- func contentHandler (kubo * kr.HttpApi , eth * ec.Client ) func (w http.ResponseWriter , r * http.Request ) {
119
+ func contentHandler (kubo * kr.HttpApi , eth * ec.Client , cache * lru. Cache [ string , Sep ] ) func (w http.ResponseWriter , r * http.Request ) {
111
120
return func (w http.ResponseWriter , r * http.Request ) {
112
121
id := chi .URLParam (r , "id" )
113
122
sub := chi .URLParam (r , "sub" )
@@ -126,7 +135,7 @@ func contentHandler(kubo *kr.HttpApi, eth *ec.Client) func(w http.ResponseWriter
126
135
127
136
log .Printf ("Attempt to find id %s" , id )
128
137
// if the cid is a sep-001 standard switch the file served
129
- if sep , err := getSepFromId (ctx , kubo , c .String ()); err == nil {
138
+ if sep , err := getSepFromId (ctx , kubo , cache , c .String ()); err == nil {
130
139
log .Printf ("Matched sep with id %s" , id )
131
140
id = sep .S .Cid
132
141
@@ -155,7 +164,7 @@ func contentHandler(kubo *kr.HttpApi, eth *ec.Client) func(w http.ResponseWriter
155
164
}
156
165
}
157
166
158
- func metaHandler (kubo * kr.HttpApi ) func (w http.ResponseWriter , r * http.Request ) {
167
+ func metaHandler (kubo * kr.HttpApi , cache * lru. Cache [ string , Sep ] ) func (w http.ResponseWriter , r * http.Request ) {
159
168
return func (w http.ResponseWriter , r * http.Request ) {
160
169
id := chi .URLParam (r , "id" )
161
170
// TODO refactor all this
@@ -171,7 +180,7 @@ func metaHandler(kubo *kr.HttpApi) func(w http.ResponseWriter, r *http.Request)
171
180
}
172
181
173
182
log .Printf ("Attempt to find id %s" , id )
174
- sep , err := getSepFromId (ctx , kubo , id )
183
+ sep , err := getSepFromId (ctx , kubo , cache , id )
175
184
if err != nil {
176
185
w .WriteHeader (http .StatusNotFound )
177
186
return
@@ -228,9 +237,20 @@ func main() {
228
237
log .Fatal (err )
229
238
}
230
239
231
- r .Get ("/content/{id}/" , contentHandler (kubo , client ))
232
- r .Get ("/content/{id}/{sub}" , contentHandler (kubo , client ))
233
- r .Get ("/metadata/{id}/" , metaHandler (kubo ))
240
+ cacheSize , err := strconv .Atoi (os .Getenv ("LRU_CACHE_SIZE" ))
241
+ if err != nil {
242
+ log .Fatal (err )
243
+ }
244
+
245
+ lruCache , err := lru.New [string , Sep ](cacheSize )
246
+ if err != nil {
247
+ log .Fatal (err )
248
+ }
249
+
250
+ log .Printf ("Cache initialized with size to %d" , cacheSize )
251
+ r .Get ("/content/{id}/" , contentHandler (kubo , client , lruCache ))
252
+ r .Get ("/content/{id}/{sub}" , contentHandler (kubo , client , lruCache ))
253
+ r .Get ("/metadata/{id}/" , metaHandler (kubo , lruCache ))
234
254
r .Get ("/healthcheck/" , health ())
235
255
236
256
// Start the node on port 8080, and log any errors
0 commit comments