Skip to content

Commit 444c6da

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 9a8b9b5 commit 444c6da

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

Dockerfile

+2-1
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 jq perl curl
4+
RUN apk --no-cache add dnsmasq jq perl curl \
5+
&& opm get pintsized/lua-resty-http
56

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

ephemeral-npm.lua

+45-1
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
local utils = require "ephemeral-utils"
34

45
local _M = {}
@@ -14,6 +15,45 @@ function _M.init()
1415
npmConfig:set('MAXAGE', _M.MAXAGE)
1516
end
1617

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

0 commit comments

Comments
 (0)