go语言协程实践:优化批量下载多个安装包进行安装的场景

效果

go语言协程实践:优化批量下载多个安装包进行安装的场景_第1张图片

package main

import (
	"fmt"
	"gitee.com/liumou_site/gcs"
	"gitee.com/liumou_site/logger"
	"strings"
	"sync"
	"time"
)

func main() {
	logger.Info("开始运行...")
	urls := []string{
		"http://clm.liumou.site/com.liumou.tools_linux-amd64_latest.deb",
		"http://clm.liumou.site/com.liumou.tools_amd64-linux_1.2.0.deb",
		"http://clm.liumou.site/com.liumou.tools_amd64-linux_1.2.1.deb",
	}

	// 使用带缓冲的通道来存储下载结果
	ch := make(chan string, len(urls))

	// 定义一个 WaitGroup,等待所有协程执行完成
	wg := sync.WaitGroup{}
	// 生产者:启动协程下载和安装软件包
	for i, url := range urls {
		wg.Add(1)

		go func(url string, i int) {
			result := downloadAndInstall(url, i)
			ch <- result // 将下载结果存入通道中
			wg.Done()
		}(url, i)
	}

	wg.Wait() // 等待所有协程执行完成
	close(ch) // 关闭通道
	for result := range ch {
		fmt.Println(result)
	}
	logger.Info("任务结束!")
}

func download(url string) error {
	logger.Debug("正在下载: ", url)
	n := gcs.NewShell()
	//n.Debug = true
	n.RunShell("wget -c ", url)
	if n.Err != nil {
		logger.Warn("下载失败: ", url)
		return n.Err
	}
	logger.Info("下载成功: ", url)
	return nil
}

func install(file string) error {
	i := gcs.NewShell()
	//i.Debug = true

	for s := 0; s < 10; s++ {
		if !i.ProcessIsRunning("dpkg") {
			logger.Debug("正在安装: ", file)
			i.RunShell("dpkg -i ", file)
			if i.Err != nil {
				logger.Error("安装失败: ", file)
				return i.Err
			}
			logger.Info("安装成功: ", file)
			return nil
		}
		logger.Debug("等待五秒后再进行安装")
		time.Sleep(5 * time.Second)
	}

	return fmt.Errorf("安装超时: %s", file)
}

func downloadAndInstall(url string, i int) string {
	// 执行下载任务
	err := download(url)
	if err != nil {
		return fmt.Sprintf("第%d个任务下载失败: %s", i+1, err.Error())
	}

	// 执行安装任务
	sp := strings.Split(url, "/")
	file := sp[len(sp)-1]
	err = install(file)
	if err != nil {
		return fmt.Sprintf("第%d个任务安装失败: %s", i+1, err.Error())
	}

	return fmt.Sprintf("第%d个任务执行成功: %s", i+1, file)
}

你可能感兴趣的:(Go,golang,linux,开发语言)