V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
PEIENYKYK
V2EX  ›  Go 编程语言

Golang 开发 web,如何控制任务启动/停止?

  •  
  •   PEIENYKYK · 2020-02-29 01:44:37 +08:00 · 3364 次点击
    这是一个创建于 1764 天前的主题,其中的信息可能已经有所发展或是发生改变。

    实在是没有什么办法才来求助各位 V2 大佬,事情是这样的。。。 我要自己实现一个 web server,用来做数据同步。其中可以添加同步任务,也可以删除同步任务,可以手动开启同步任务,也可以停止。 以上是需求,现在小弟遇到了一个棘手问题。 在前端请求任务开始,这个很简单,我可以利用 go Startsync(id),这个 id 是小弟自己定义的任务 id,任务很可能有多个,如果停止任务呢?比如一个任务的 id 是 123,那么我现在要停止 123 这个任务,我该怎么做呢?冥思苦想好几天了,想过一些别的方法,比如在数据库中写入一个变量,停止任务时候修改这个变量,同步任务会不断请求这个参数,一旦发生变化,就 exit 任务。这是小弟想到的办法,请各位 V2 大佬给小弟一些灵感吧。拜谢,谨再拜。

    12 条回复    2020-03-01 00:42:39 +08:00
    Srar
        1
    Srar  
       2020-02-29 02:17:44 +08:00
    建立一个任务 ID 与 context 的对应 map 开任务时候创建一个 context 存入 map 中 停止任务通过任务 ID 去找 context 给 cancel 掉

    https://golang.org/pkg/context/
    mornlight
        2
    mornlight  
       2020-02-29 03:01:38 +08:00 via iPhone
    @Srar 你只告诉楼主这个思路可能不太够,还要加上任务执行过程中要有「检测 context 的逻辑」。

    楼主可以提供多一些信息:task 是什么性质?无限循环还是定时运行?一次执行时间多长?执行一半强行中断有没有副作用?

    从大的思路上说,因为你没法拿到一个 goroutine 的 id 然后把这个 goroutine 杀掉,所以一定是在任务执行过程中有业务代码检测是否要停止执行,这个检测怎么实现就要看场景了,一楼提到的 context 很适合干这事。
    Srar
        3
    Srar  
       2020-02-29 04:11:29 +08:00 via iPhone
    @mornlight 是的 忘记告诉需要有一个检测过程了
    1wlinesperday
        4
    1wlinesperday  
       2020-02-29 09:32:22 +08:00
    用 context 就可以了,这个很容易 cancel 的。
    alexsunxl
        5
    alexsunxl  
       2020-02-29 09:54:24 +08:00
    用 context 这种依赖 runtime 的方式, 你要横向拓展多起几个 pod 的时候,不是很痛苦吗

    除非这个服务一直玩单进程
    JackyCDK
        6
    JackyCDK  
       2020-02-29 12:28:39 +08:00
    context with cancel?
    encro
        7
    encro  
       2020-02-29 17:46:57 +08:00
    一切通讯都是信号,利用好信号,没有不能达到的
    encro
        8
    encro  
       2020-02-29 17:49:34 +08:00
    看下 frp,nps,goproxy 的代码,或者搜一下 go 语言+内网穿透
    fizzday
        9
    fizzday  
       2020-02-29 19:26:43 +08:00
    useben
        10
    useben  
       2020-02-29 20:24:37 +08:00
    一楼的做法就行。每启动一个 task,分配 task id 和 context.without()并用一个 map 来存放映射关系,context 传入 task goroutine。启动个主循环检测取消 task chan,停止 api 收到停止,往取消 task chan 传入 task id 就行了。那边的主循环就收到 chan 的 task id,就去找到对应的 context,done()就 O 了。。。
    useben
        11
    useben  
       2020-02-29 20:24:54 +08:00
    context with cancel
    labulaka521
        12
    labulaka521  
       2020-03-01 00:42:39 +08:00 via Android
    https://www.v2ex.com/t/648602 基本满足你你要求
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   942 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 22:25 · PVG 06:25 · LAX 14:25 · JFK 17:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.