aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2019-04-01 21:23:53 -0300
committerHisham Muhammad <hisham@gobolinux.org>2019-04-03 10:44:51 -0300
commitb3d36513baa15b5c7b4c1ad24f655e3469b83dc5 (patch)
tree3c1aa0ad6c894486b5d9c39c83bf12196936549a /src
parent1ebc96ac47b72b9c7c226f14cd018ef5e4d62a74 (diff)
downloadluarocks-b3d36513baa15b5c7b4c1ad24f655e3469b83dc5.tar.gz
luarocks-b3d36513baa15b5c7b4c1ad24f655e3469b83dc5.tar.bz2
luarocks-b3d36513baa15b5c7b4c1ad24f655e3469b83dc5.zip
Cache manifest more aggressively
* Introduce cache_timeout config option (default 10 seconds) * Do not re-check for the last-modified time of a file to be downloaded for cfg.cache_timeout seconds * Do not re-unzip if zip file was fetched from cache
Diffstat (limited to 'src')
-rw-r--r--src/luarocks/core/cfg.lua2
-rw-r--r--src/luarocks/fetch.lua17
-rw-r--r--src/luarocks/fs/lua.lua49
-rw-r--r--src/luarocks/fs/tools.lua1
-rw-r--r--src/luarocks/manif.lua24
5 files changed, 65 insertions, 28 deletions
diff --git a/src/luarocks/core/cfg.lua b/src/luarocks/core/cfg.lua
index c6824153..859f77e0 100644
--- a/src/luarocks/core/cfg.lua
+++ b/src/luarocks/core/cfg.lua
@@ -188,6 +188,8 @@ local function make_defaults(lua_version, target_cpu, platforms, home)
188 hooks_enabled = true, 188 hooks_enabled = true,
189 deps_mode = "one", 189 deps_mode = "one",
190 check_certificates = false, 190 check_certificates = false,
191
192 cache_timeout = 10,
191 193
192 lua_modules_path = "/share/lua/"..lua_version, 194 lua_modules_path = "/share/lua/"..lua_version,
193 lib_modules_path = "/lib/lua/"..lua_version, 195 lib_modules_path = "/lib/lua/"..lua_version,
diff --git a/src/luarocks/fetch.lua b/src/luarocks/fetch.lua
index 8fa7d6a6..6835462a 100644
--- a/src/luarocks/fetch.lua
+++ b/src/luarocks/fetch.lua
@@ -21,9 +21,16 @@ local cfg = require("luarocks.core.cfg")
21-- filename can be given explicitly as this second argument. 21-- filename can be given explicitly as this second argument.
22-- @param cache boolean: compare remote timestamps via HTTP HEAD prior to 22-- @param cache boolean: compare remote timestamps via HTTP HEAD prior to
23-- re-downloading the file. 23-- re-downloading the file.
24-- @return string or (nil, string, [string]): the absolute local pathname for the 24-- @return (string, nil, nil, boolean) or (nil, string, [string]):
25-- fetched file, or nil and a message in case of errors, followed by 25-- in case of success:
26-- an optional error code. 26-- * the absolute local pathname for the fetched file
27-- * nil
28-- * nil
29-- * `true` if the file was fetched from cache
30-- in case of failure:
31-- * nil
32-- * an error message
33-- * an optional error code.
27function fetch.fetch_url(url, filename, cache) 34function fetch.fetch_url(url, filename, cache)
28 assert(type(url) == "string") 35 assert(type(url) == "string")
29 assert(type(filename) == "string" or not filename) 36 assert(type(filename) == "string" or not filename)
@@ -32,11 +39,11 @@ function fetch.fetch_url(url, filename, cache)
32 if protocol == "file" then 39 if protocol == "file" then
33 return fs.absolute_name(pathname) 40 return fs.absolute_name(pathname)
34 elseif dir.is_basic_protocol(protocol) then 41 elseif dir.is_basic_protocol(protocol) then
35 local ok, name = fs.download(url, filename, cache) 42 local ok, name, from_cache = fs.download(url, filename, cache)
36 if not ok then 43 if not ok then
37 return nil, "Failed downloading "..url..(filename and " - "..filename or ""), "network" 44 return nil, "Failed downloading "..url..(filename and " - "..filename or ""), "network"
38 end 45 end
39 return name 46 return name, nil, nil, from_cache
40 else 47 else
41 return nil, "Unsupported protocol "..protocol 48 return nil, "Unsupported protocol "..protocol
42 end 49 end
diff --git a/src/luarocks/fs/lua.lua b/src/luarocks/fs/lua.lua
index 6625ddda..313204b9 100644
--- a/src/luarocks/fs/lua.lua
+++ b/src/luarocks/fs/lua.lua
@@ -734,6 +734,14 @@ local function request(url, method, http, loop_control)
734 end 734 end
735end 735end
736 736
737local function write_timestamp(filename, data)
738 local utfd = io.open(filename, "w")
739 if utfd then
740 utfd:write(data)
741 utfd:close()
742 end
743end
744
737-- @param url string: URL to fetch. 745-- @param url string: URL to fetch.
738-- @param filename string: local filename of the file to fetch. 746-- @param filename string: local filename of the file to fetch.
739-- @param http table: The library to use (http from LuaSocket or LuaSec) 747-- @param http table: The library to use (http from LuaSocket or LuaSec)
@@ -747,12 +755,25 @@ local function http_request(url, filename, http, cache)
747 if tsfd then 755 if tsfd then
748 local timestamp = tsfd:read("*a") 756 local timestamp = tsfd:read("*a")
749 tsfd:close() 757 tsfd:close()
758 local unixtime
759 local utfd = io.open(filename..".unixtime", "r")
760 if utfd then
761 unixtime = tonumber(utfd:read("*a"))
762 utfd:close()
763 end
764 if unixtime then
765 if os.time() - unixtime < cfg.cache_timeout then
766 return true, nil, nil, true
767 end
768 end
769
750 local result, status, headers, err = request(url, "HEAD", http) 770 local result, status, headers, err = request(url, "HEAD", http)
751 if not result then 771 if not result then
752 return nil, status, headers 772 return nil, status, headers
753 end 773 end
754 if status == 200 and headers["last-modified"] == timestamp then 774 if status == 200 and headers["last-modified"] == timestamp then
755 return true 775 write_timestamp(filename .. ".unixtime", os.time())
776 return true, nil, nil, true
756 end 777 end
757 end 778 end
758 end 779 end
@@ -761,11 +782,8 @@ local function http_request(url, filename, http, cache)
761 return nil, status, headers 782 return nil, status, headers
762 end 783 end
763 if cache and headers["last-modified"] then 784 if cache and headers["last-modified"] then
764 local tsfd = io.open(filename..".timestamp", "w") 785 write_timestamp(filename .. ".timestamp", headers["last-modified"])
765 if tsfd then 786 write_timestamp(filename .. ".unixtime", os.time())
766 tsfd:write(headers["last-modified"])
767 tsfd:close()
768 end
769 end 787 end
770 local file = io.open(filename, "wb") 788 local file = io.open(filename, "wb")
771 if not file then return nil, 0, {} end 789 if not file then return nil, 0, {} end
@@ -796,8 +814,14 @@ local downloader_warning = false
796-- resulting local filename of the remote file as the basename of the URL; 814-- resulting local filename of the remote file as the basename of the URL;
797-- if that is not correct (due to a redirection, for example), the local 815-- if that is not correct (due to a redirection, for example), the local
798-- filename can be given explicitly as this second argument. 816-- filename can be given explicitly as this second argument.
799-- @return (boolean, string): true and the filename on success, 817-- @return (boolean, string, boolean):
800-- false and the error message on failure. 818-- In case of success:
819-- * true
820-- * a string with the filename
821-- * true if the file was retrieved from local cache
822-- In case of failure:
823-- * false
824-- * error message
801function fs_lua.download(url, filename, cache) 825function fs_lua.download(url, filename, cache)
802 assert(type(url) == "string") 826 assert(type(url) == "string")
803 assert(type(filename) == "string" or not filename) 827 assert(type(filename) == "string" or not filename)
@@ -809,15 +833,16 @@ function fs_lua.download(url, filename, cache)
809 return fs.use_downloader(url, filename, cache) 833 return fs.use_downloader(url, filename, cache)
810 end 834 end
811 835
812 local ok, err, https_err 836 local ok, err, https_err, from_cache
813 if util.starts_with(url, "http:") then 837 if util.starts_with(url, "http:") then
814 ok, err, https_err = http_request(url, filename, http, cache) 838 ok, err, https_err, from_cache = http_request(url, filename, http, cache)
815 elseif util.starts_with(url, "ftp:") then 839 elseif util.starts_with(url, "ftp:") then
816 ok, err = ftp_request(url, filename) 840 ok, err = ftp_request(url, filename)
817 elseif util.starts_with(url, "https:") then 841 elseif util.starts_with(url, "https:") then
818 -- skip LuaSec when proxy is enabled since it is not supported 842 -- skip LuaSec when proxy is enabled since it is not supported
819 if luasec_ok and not os.getenv("https_proxy") then 843 if luasec_ok and not os.getenv("https_proxy") then
820 ok, err = http_request(url, filename, https, cache) 844 local _
845 ok, err, _, from_cache = http_request(url, filename, https, cache)
821 else 846 else
822 https_err = true 847 https_err = true
823 end 848 end
@@ -834,7 +859,7 @@ function fs_lua.download(url, filename, cache)
834 elseif not ok then 859 elseif not ok then
835 return nil, err 860 return nil, err
836 end 861 end
837 return true, filename 862 return true, filename, from_cache
838end 863end
839 864
840else --...if socket_ok == false then 865else --...if socket_ok == false then
diff --git a/src/luarocks/fs/tools.lua b/src/luarocks/fs/tools.lua
index 52915781..ef5abe63 100644
--- a/src/luarocks/fs/tools.lua
+++ b/src/luarocks/fs/tools.lua
@@ -154,6 +154,7 @@ function tools.use_downloader(url, filename, cache)
154 if cache then 154 if cache then
155 -- --timestamping is incompatible with --output-document, 155 -- --timestamping is incompatible with --output-document,
156 -- but that's not a problem for our use cases. 156 -- but that's not a problem for our use cases.
157 fs.delete(filename .. ".unixtime")
157 fs.change_dir(dir.dir_name(filename)) 158 fs.change_dir(dir.dir_name(filename))
158 ok = fs.execute_quiet(wget_cmd.." --timestamping ", url) 159 ok = fs.execute_quiet(wget_cmd.." --timestamping ", url)
159 fs.pop_dir() 160 fs.pop_dir()
diff --git a/src/luarocks/manif.lua b/src/luarocks/manif.lua
index 0bef6f13..9026bc5b 100644
--- a/src/luarocks/manif.lua
+++ b/src/luarocks/manif.lua
@@ -74,11 +74,11 @@ local function fetch_manifest_from(repo_url, filename)
74 if not ok then 74 if not ok then
75 return nil, "Failed creating temporary cache directory "..cache_dir 75 return nil, "Failed creating temporary cache directory "..cache_dir
76 end 76 end
77 local file, err, errcode = fetch.fetch_url(url, dir.path(cache_dir, filename), true) 77 local file, err, errcode, from_cache = fetch.fetch_url(url, dir.path(cache_dir, filename), true)
78 if not file then 78 if not file then
79 return nil, "Failed fetching manifest for "..repo_url..(err and " - "..err or ""), errcode 79 return nil, "Failed fetching manifest for "..repo_url..(err and " - "..err or ""), errcode
80 end 80 end
81 return file 81 return file, nil, nil, from_cache
82end 82end
83 83
84--- Load a local or remote manifest describing a repository. 84--- Load a local or remote manifest describing a repository.
@@ -106,7 +106,7 @@ function manif.load_manifest(repo_url, lua_version)
106 } 106 }
107 107
108 local protocol, repodir = dir.split_url(repo_url) 108 local protocol, repodir = dir.split_url(repo_url)
109 local pathname 109 local pathname, from_cache
110 if protocol == "file" then 110 if protocol == "file" then
111 for _, filename in ipairs(filenames) do 111 for _, filename in ipairs(filenames) do
112 pathname = dir.path(repodir, filename) 112 pathname = dir.path(repodir, filename)
@@ -117,7 +117,7 @@ function manif.load_manifest(repo_url, lua_version)
117 else 117 else
118 local err, errcode 118 local err, errcode
119 for _, filename in ipairs(filenames) do 119 for _, filename in ipairs(filenames) do
120 pathname, err, errcode = fetch_manifest_from(repo_url, filename) 120 pathname, err, errcode, from_cache = fetch_manifest_from(repo_url, filename)
121 if pathname then 121 if pathname then
122 break 122 break
123 end 123 end
@@ -131,13 +131,15 @@ function manif.load_manifest(repo_url, lua_version)
131 local dirname = dir.dir_name(pathname) 131 local dirname = dir.dir_name(pathname)
132 fs.change_dir(dirname) 132 fs.change_dir(dirname)
133 local nozip = pathname:match("(.*)%.zip$") 133 local nozip = pathname:match("(.*)%.zip$")
134 fs.delete(nozip) 134 if not from_cache then
135 local ok, err = fs.unzip(pathname) 135 fs.delete(nozip)
136 fs.pop_dir() 136 local ok, err = fs.unzip(pathname)
137 if not ok then 137 fs.pop_dir()
138 fs.delete(pathname) 138 if not ok then
139 fs.delete(pathname..".timestamp") 139 fs.delete(pathname)
140 return nil, "Failed extracting manifest file: " .. err 140 fs.delete(pathname..".timestamp")
141 return nil, "Failed extracting manifest file: " .. err
142 end
141 end 143 end
142 pathname = nozip 144 pathname = nozip
143 end 145 end