Rust任务集群下载工具库taskcluster-download的使用,高效管理TaskCluster任务资源下载

Rust任务集群下载工具库taskcluster-download的使用,高效管理TaskCluster任务资源下载

Taskcluster Download Support

这个库是Taskcluster客户端的配套工具,提供了下载对象的功能支持。

使用方法

以下是使用taskcluster-download库进行任务资源下载的完整示例:

use taskcluster_download::Downloader;
use taskcluster::Client;
use std::path::PathBuf;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建Taskcluster客户端
    let client = Client::new(
        "https://taskcluster.net".to_string(),
        "your_client_id".to_string(),
        "your_access_token".to_string(),
    )?;

    // 创建下载器实例
    let downloader = Downloader::new(client);
    
    // 定义要下载的任务ID和工件路径
    let task_id = "some-task-id";
    let artifact_path = "public/build/target.zip";
    
    // 设置本地保存路径
    let destination = PathBuf::from("/tmp/downloaded_file.zip");
    
    // 执行下载
    downloader.download_artifact_to_file(task_id, artifact_path, &destination).await?;
    
    println!("文件已下载到: {:?}", destination);
    
    Ok(())
}

兼容性

该库与Taskcluster本身共享版本号。也就是说,版本号为x.y.z的客户端包含对应于Taskcluster版本x.y.z的API方法。Taskcluster非常注重API兼容性,并保证在主版本内保持兼容。这意味着任何x.*版本的客户端都能与x.*版本的Taskcluster服务正常工作,并且很可能与许多其他主版本的Taskcluster服务兼容。任何不兼容性都会在变更日志中注明。

安装

在项目目录中运行以下Cargo命令:

cargo add taskcluster-download

或者在Cargo.toml中添加以下行:

taskcluster-download = "88.0.2"

许可证

MPL-2.0

完整示例代码

use taskcluster_download::Downloader;
use taskcluster::Client;
use std::path::PathBuf;
use std::error::Error;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // 1. 初始化Taskcluster客户端
    // 注意:替换成您自己的凭证信息
    let client = Client::new(
        "https://taskcluster.net".to_string(),
        "your_client_id".to_string(),
        "your_access_token".to_string(),
    )?;

    // 2. 创建下载器实例
    let downloader = Downloader::new(client);
    
    // 3. 设置下载参数
    let task_id = "CI-build-task-12345"; // 替换为实际任务ID
    let artifact_path = "public/build/release.zip"; // 替换为实际工件路径
    let destination = PathBuf::from("/tmp/build_artifacts/release.zip"); // 设置本地保存路径
    
    // 4. 确保目标目录存在
    if let Some(parent) = destination.parent() {
        tokio::fs::create_dir_all(parent).await?;
    }
    
    // 5. 执行下载
    println!("开始下载任务 {} 的工件 {}...", task_id, artifact_path);
    downloader.download_artifact_to_file(task_id, artifact_path, &destination).await?;
    
    // 6. 输出结果
    println!("下载完成!文件已保存到: {:?}", destination);
    println!("文件大小: {} bytes", tokio::fs::metadata(&destination).await?.len());
    
    Ok(())
}

示例说明

  1. 首先创建Taskcluster客户端,需要提供:

    • Taskcluster服务地址
    • 您的客户端ID
    • 访问令牌
  2. 创建Downloader实例,它将用于管理下载过程

  3. 设置下载参数:

    • task_id: 要下载的任务ID
    • artifact_path: 工件在任务中的路径
    • destination: 本地文件保存路径
  4. 确保目标目录存在,不存在则创建

  5. 调用download_artifact_to_file方法执行下载

  6. 下载完成后显示文件保存路径和大小

注意事项

  • 需要tokio运行时,确保Cargo.toml中有tokio依赖
  • 需要网络连接访问Taskcluster服务
  • 确保有足够的磁盘空间存放下载文件
  • 凭证信息需要妥善保管,不要硬编码在代码中

1 回复

Rust任务集群下载工具库taskcluster-download的使用指南

概述

taskcluster-download是一个用于高效管理TaskCluster任务资源下载的Rust库。它提供了简单易用的API来从TaskCluster任务中下载工件(artifacts),特别适合需要批量处理多个任务下载的场景。

主要特性

  • 支持并发下载多个工件
  • 自动处理TaskCluster认证
  • 提供进度报告功能
  • 支持断点续传
  • 可配置的并发度和重试策略

安装方法

在项目的Cargo.toml中添加依赖:

[dependencies]
taskcluster-download = "0.3"
tokio = { version = "1", features = ["full"] }

完整示例代码

下面是一个完整的示例,展示了如何使用taskcluster-download库进行下载操作:

use taskcluster_download::{Downloader, DownloadRequest, ProgressReporter, RetryPolicy};
use std::path::PathBuf;
use std::time::Duration;

// 自定义进度报告器
#[derive(Default)]
struct ConsoleReporter;

impl ProgressReporter for ConsoleReporter {
    fn on_progress(&self, downloaded: u64, total: Option<u64>) {
        match total {
            Some(total) => println!("进度: {}/{} ({}%)", 
                downloaded, 
                total,
                (downloaded as f64 / total as f64 * 100.0) as u32),
            None => println!("已下载: {} bytes", downloaded),
        }
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 创建下载器实例
    let downloader = Downloader::builder()
        .root_url("https://taskcluster.net")  // TaskCluster根URL
        .concurrency(4)  // 并发下载数
        .retry_policy(RetryPolicy {
            max_retries: 3,  // 最大重试次数
            min_delay: Duration::from_secs(1),  // 最小重试延迟
            max_delay: Duration::from_secs(10),  // 最大重试延迟
        })
        .progress_reporter(ConsoleReporter::default())  // 进度报告
        .build()?;
    
    // 2. 准备下载任务
    let requests = vec![
        DownloadRequest {
            task_id: "TASK-123".to_string(),  // 任务ID
            artifact_path: "public/build/app.zip".to_string(),  // 工件路径
            save_path: PathBuf::from("./downloads/app.zip"),  // 保存路径
        },
        DownloadRequest {
            task_id: "TASK-456".to_string(),
            artifact_path: "public/logs/debug.log".to_string(),
            save_path: PathBuf::from("./logs/debug.log"),
        },
    ];
    
    // 3. 执行批量下载
    match downloader.download_batch("PROJECT-ID", requests).await {
        Ok(_) => println!("所有下载任务完成"),
        Err(e) => eprintln!("下载失败: {}", e),
    }
    
    Ok(())
}

代码说明

  1. 自定义进度报告器

    • 实现了ProgressReporter trait来显示下载进度
    • 同时处理有总大小和没有总大小的情况
  2. 下载器配置

    • 设置TaskCluster根URL
    • 配置并发数为4
    • 设置重试策略(最多3次,延迟1-10秒)
    • 添加进度报告器
  3. 下载请求

    • 创建了两个下载请求
    • 分别下载构建产物和日志文件
  4. 错误处理

    • 使用match处理批量下载结果
    • 打印成功或失败信息

最佳实践建议

  1. 对于生产环境,建议将认证信息存储在环境变量中:

    .credentials(taskcluster::Credentials {
        client_id: std::env::var("TASKCLUSTER_CLIENT_ID")?,
        access_token: std::env::var("TASKCLUSTER_ACCESS_TOKEN")?,
        certificate: None,
    })
    
  2. 对于大文件下载,考虑使用临时文件:

    let temp_path = save_path.with_extension("download");
    // 下载完成后
    std::fs::rename(temp_path, save_path)?;
    
  3. 监控下载速度:

    fn on_progress(&self, downloaded: u64, _: Option<u64>) {
        let now = std::time::Instant::now();
        let elapsed = now.duration_since(self.last_time).as_secs_f64();
        if elapsed > 1.0 {  // 每秒更新一次
            let speed = (downloaded - self.last_bytes) as f64 / elapsed;
            println!("下载速度: {:.2} KB/s", speed / 1024.0);
            self.last_bytes = downloaded;
            self.last_time = now;
        }
    }
    
回到顶部