Golang(10):使用Golang中的goroutine 做一个简单的后台任务,比如下载文件,然后放到 map 存储,使用另外一个接口进行check检查状态。可以支持多个任务,使用jobId区分 - Go语言中文社区

Golang(10):使用Golang中的goroutine 做一个简单的后台任务,比如下载文件,然后放到 map 存储,使用另外一个接口进行check检查状态。可以支持多个任务,使用jobId区分


前言


相关Golang 全部分类:
https://blog.csdn.net/freewebsys/category_2120333.html

本文的原文连接是:
https://blog.csdn.net/freewebsys/article/details/105003261

未经博主允许不得转载。
博主地址是:http://blog.csdn.net/freewebsys

1,关于Golang 中goroutine


使用Golang中的goroutine 做一个简单的后台任务,比如下载文件,然后放到 map 存储,使用另外一个接口进行check检查状态。可以支持多个任务,使用jobId区分。

golang 处理速度非常快,但是在和其他服务进行对接的时候,比如下载任务。
需要放到后台执行,而且要检查状态。

需要开发两个 http 接口。一个作为创建任务,一个检查任务状态。
同时使用最简单的sync lock 锁住。防止并发问题。不知道对不对。

2,代码


package main

import (
	"fmt"
	"log"
	"net/http"
	"strings"
	"sync"
	"time"
)

// 先声明map
var statusMap = make(map[string]string)
var memoryAccess sync.Mutex

func create(w http.ResponseWriter, req *http.Request) {

	rawQuery := req.URL.RawQuery
	if !strings.Contains(rawQuery,"jobId=") {
		fmt.Fprintf(w, `{"message" :"jobId is not exist ."}`)
	}
	jobId := strings.Replace(rawQuery,"jobId=","",-1)

	if !strings.Contains(rawQuery,"jobId=") {
		fmt.Fprintf(w, `{"message" :"jobId is empty ."}`)
	}
	// 传入参数。
	go func(statusMap map[string]string) {
		for i := 0; i <= 10; i++ {

			//使用最简单的加个锁。
			memoryAccess.Lock()
			if i == 10 {
				statusMap[jobId] = `{"message" :"finish"}`
				//return //如果不解锁看看效果。
			} else {
				statusMap[jobId] = `{"message" :"downloading"}`
			}
			memoryAccess.Unlock()
			// 暂停 1 秒
			time.Sleep(1 * time.Second)
			log.Println(statusMap)

		}

		//新增一个5秒执行一次的计时器
		ticker := time.NewTicker(5 * time.Second)
		defer func(){
			//使用最简单的加个锁。
			memoryAccess.Lock()
			delete(statusMap,jobId)//不存在没有关系。
			memoryAccess.Unlock()
			ticker.Stop()
			log.Println("clear job id ")
		}()
		
	}(statusMap)

	fmt.Fprintf(w, `{"message" :"create job"}`)
}

func check(w http.ResponseWriter, req *http.Request) {

	rawQuery := req.URL.RawQuery
	jobId := strings.Replace(rawQuery,"jobId=","",-1)
	if strTmp, ok := statusMap[jobId]; ok {
		//存在
		fmt.Fprintf(w, strTmp)
	}else {
		msg := fmt.Sprintf(`{"message" :"%s jobId no found ."}`,jobId)
		fmt.Fprintf(w, msg)
	}
}

func headers(w http.ResponseWriter, req *http.Request) {

	for name, headers := range req.Header {
		for _, h := range headers {
			fmt.Fprintf(w, "%v: %vn", name, h)
		}
	}
}

func main() {

	http.HandleFunc("/job/create", create)
	http.HandleFunc("/job/check", check)
	// 测试 head 头信息。
	http.HandleFunc("/headers", headers)

	http.ListenAndServe(":8090", nil)
}

效果:
http://localhost:8090/job/create?jobId=2021
http://localhost:8090/job/check?jobId=2021
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

3,总结


代码是一方面,后续还要考虑下逻辑。在创建任务之后,最后定时 5 秒把 map 的数据删除。防止,程序运行map 越来越大。
同时等待 5 秒钟时间,给 http 请求做好 check 时间。能够访问到 finish 的数据。
要不然数据直接就没有了。后续可以通过 chanel 在优化下。

本文的原文连接是:
https://blog.csdn.net/freewebsys/article/details/105003261

博主地址是:https://blog.csdn.net/freewebsys

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/freewebsys/article/details/105003261
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-04-18 17:43:22
  • 阅读 ( 1455 )
  • 分类:Go

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢