Class: Factorix::Transfer::Downloader
- Inherits:
-
Object
- Object
- Factorix::Transfer::Downloader
- Defined in:
- lib/factorix/transfer/downloader.rb
Overview
File downloader with caching and progress tracking
Downloads files from HTTPS URLs with automatic caching. Uses file locking to prevent concurrent downloads of the same file. HTTP redirects are handled automatically by the HTTP layer. Publishes progress events during download.
Instance Method Summary collapse
-
#download(url, output, expected_sha1: nil) ⇒ void
Download a file from the given URL with caching support.
Instance Method Details
#download(url, output, expected_sha1: nil) ⇒ void
This method returns an undefined value.
Download a file from the given URL with caching support.
If the file exists in cache, it will be copied from cache instead of downloading. If the cached file fails SHA1 verification, it will be invalidated and re-downloaded. If multiple processes attempt to download the same file, only one will download while others wait for the download to complete. HTTP redirects are followed automatically by the HTTP layer.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/factorix/transfer/downloader.rb', line 49 def download(url, output, expected_sha1: nil) unless url.is_a?(URI::HTTPS) logger.error "Invalid URL: must be HTTPS" raise URLError, "URL must be HTTPS" end logger.info("Starting download", output: output.to_s) cache_key = strip_query(url) case try_cache_hit(cache_key, output, expected_sha1:) when :hit return when :miss logger.debug("Cache miss, downloading", output: output.to_s) publish("cache.miss", output: output.to_s) when :corrupted logger.debug("Re-downloading after cache invalidation", output: output.to_s) publish("cache.miss", output: output.to_s) else raise RuntimeError, "Unexpected cache state" end cache.with_lock(cache_key) do return if try_cache_hit(cache_key, output, expected_sha1:) == :hit with_temporary_file do |temp_file| download_file_with_progress(url, temp_file) verify_sha1(temp_file, expected_sha1) if expected_sha1 cache.store(cache_key, temp_file) cache.write_to(cache_key, output) end end end |