diff options
author | Hisham Muhammad <hisham@gobolinux.org> | 2019-04-01 21:23:53 -0300 |
---|---|---|
committer | Hisham Muhammad <hisham@gobolinux.org> | 2019-04-03 10:44:51 -0300 |
commit | b3d36513baa15b5c7b4c1ad24f655e3469b83dc5 (patch) | |
tree | 3c1aa0ad6c894486b5d9c39c83bf12196936549a /src | |
parent | 1ebc96ac47b72b9c7c226f14cd018ef5e4d62a74 (diff) | |
download | luarocks-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.lua | 2 | ||||
-rw-r--r-- | src/luarocks/fetch.lua | 17 | ||||
-rw-r--r-- | src/luarocks/fs/lua.lua | 49 | ||||
-rw-r--r-- | src/luarocks/fs/tools.lua | 1 | ||||
-rw-r--r-- | src/luarocks/manif.lua | 24 |
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. | ||
27 | function fetch.fetch_url(url, filename, cache) | 34 | function 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 |
735 | end | 735 | end |
736 | 736 | ||
737 | local 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 | ||
743 | end | ||
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 | ||
801 | function fs_lua.download(url, filename, cache) | 825 | function 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 |
838 | end | 863 | end |
839 | 864 | ||
840 | else --...if socket_ok == false then | 865 | else --...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 |
82 | end | 82 | end |
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 |