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 |
