Skip to content

Commit 63b6542

Browse files
committed
pre-cache related packages when caching
This results in the registry pre-warm itself in response to the first request.
1 parent 34d4468 commit 63b6542

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
FROM openresty/openresty:alpine
22
MAINTAINER Ryan Graham <[email protected]>
33

4-
RUN apk --no-cache add dnsmasq
4+
RUN apk --no-cache add dnsmasq perl curl \
5+
&& opm get pintsized/lua-resty-http
56

67
ADD entrypoint.sh nginx.conf ephemeral-npm.lua /
78

ephemeral-npm.lua

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
local cjson = require "cjson.safe"
2+
local http = require "resty.http"
23

34
local _M = {}
45

@@ -18,6 +19,44 @@ function _M.init()
1819
npmConfig:set('MAXAGE', _M.MAXAGE)
1920
end
2021

22+
function _M.prefetchRelatedPackages(premature, selfHost, pkg)
23+
local httpc = http.new()
24+
httpc:connect('127.0.0.1', 4873)
25+
local distTags = pkg['dist-tags'] or {}
26+
local versions = pkg.versions or {}
27+
local latestVersion = distTags.latest
28+
local latest = versions[latestVersion] or {}
29+
local deps = latest.dependencies or {}
30+
local reqs = {}
31+
-- find any deps that we haven't already seen and queue them for fetching
32+
for k, v in pairs(deps) do
33+
if meta:get('/' .. k) == nil then
34+
table.insert(reqs, {
35+
path = '/' .. k,
36+
method = 'GET',
37+
headers = {
38+
["Host"] = selfHost,
39+
},
40+
})
41+
end
42+
end
43+
-- extract all the tarball URLs and fetch them to force them to be cached
44+
for v,p in pairs(versions) do
45+
local scheme, host, port, path, query = unpack(httpc:parse_uri(p.dist.tarball))
46+
table.insert(reqs, {
47+
path = path,
48+
method = 'GET',
49+
})
50+
end
51+
local responses, err = httpc:request_pipeline(reqs)
52+
for i,r in ipairs(responses) do
53+
if r.status then
54+
r:read_body() -- to oblivion!
55+
end
56+
end
57+
httpc:close()
58+
end
59+
2160
function _M.getPackage()
2261
local uri = ngx.var.uri
2362
local meta = ngx.shared.npmMeta
@@ -37,10 +76,14 @@ function _M.getPackage()
3776
return ngx.redirect(uri, ngx.HTTP_MOVED_TEMPORARILY)
3877
end
3978
meta:set(uri, body, _M.MAXAGE)
79+
-- We rewrite the URLs AFTER caching so that we can be accessed by
80+
-- any hostname that is pointed at us.
81+
body = string.gsub(body, _M.hostPattern, base)
82+
ngx.timer.at(0.1, _M.prefetchRelatedPackages, ngx.var.http_host, pkgJSON)
4083
else
84+
body = string.gsub(body, _M.hostPattern, base)
4185
ngx.var.ephemeralCacheStatus = 'HIT'
4286
end
43-
body = string.gsub(body, _M.hostPattern, base)
4487
ngx.header["Content-Length"] = #body
4588
ngx.print(body)
4689
end

0 commit comments

Comments
 (0)