yuzd / Hangfire.HttpJob

httpjob for Hangfire,restful api for Hangfire,job调度与业务分离
https://github.com/yuzd/Hangfire.HttpJob/wiki
MIT License
628 stars 185 forks source link

一个job顺序调用多个api #32

Closed xgsince closed 4 years ago

xgsince commented 4 years ago

首先表示感谢,非常棒的库! 一个应用场景: 厂商A拥有api1,厂商二拥有api2,因其功能,我作为调用者必须依次调用。这在数据中心的数据处理中很常见。

所以,能否实现这样的功能,在option或面板配置时支持列表(或者说json数组),类似 { "JobName": "job1", "同步或异步":"同步是为了顺序执行,异步则跟目前的功能没多大区别,只是把需要在一个时间段要干的活打包了一下" "services": [ { "Method": "GET", "ContentType": "application/json", "Url": "http://", "Headers": {}, "Data": {} }, { "Method": "GET", "ContentType": "application/json", "Url": "http://", "Headers": {}, "Data": {} } ] }

yuzd commented 4 years ago

我们讨论下 一个配置里面顺序发起多个httpjob的调用请求, 我在考虑按照如下的结构比较好?

image

如上图: 增加一个 Child 属性结构就是它本身。 在第一个job1 调用完成之后继续调用 job2.以此类推完顺序执行。

xgsince commented 4 years ago

子job,非常好的构思! 一个建议:job1可以把执行的结果当成参数传给job2,当然需要设置[启用传参],否则执行配置的参数。还可以,设置什么情况下调用job2,如job1成功时,失败时,完成时。 一个讨论:一个配置是queue一个job;或是queue多个job,即在执行完job1后,把job2单独queue。 如何选择? @yuzd

yuzd commented 4 years ago
一个建议:job1可以把执行的结果当成参数传给job2,当然需要设置[启用传参],否则执行配置的参数。还可以,设置什么情况下调用job2,如job1成功时,失败时,完成时。

===》这个建议可以。在子job里面多预留一个参数作为上一个job的返回值传进来。

一个讨论:一个配置是queue一个job;或是queue多个job,即在执行完job1后,把job2单独queue。

===> 你是想子job在不同的queue?

xgsince commented 4 years ago

可能我表达不清楚,queue是同一个,我想讨论的是子job是否单独生成一个job执行。 我的看法: (必要)一个job:配置的job执行job1和job2,优点是日志集中,方便查看; (可选)多个job:配置的job执行job1,job2单独生成job执行,类似hangfire的ContinueWith。优点是方便子job重试,即job1成功job2失败,可以很方便重试job2而不用执行job1。

当然最后支持哪一种,或者两种都支持,还得 @yuzd 大神考虑决定。

yuzd commented 4 years ago
(必要)一个job:配置的job执行job1和job2,优点是日志集中,方便查看;
(可选)多个job:配置的job执行job1,job2单独生成job执行,类似hangfire的ContinueWith

这2个选项好像有冲突,你想要日志集中查看的话,必须是以一个job来执行所有的任务和子任务,如果以多job的形式执行子任务的话[利用hangfire的ContinueWith],看日志就得查看多个。因为hangfire是以job为单位来的。

xgsince commented 4 years ago

(必要)指必要支持,作为默认模式,或者简单模式,一切都在job内执行; (可选)指可以支持,作为显示指定的模式,灵活模式,如:子job中设置节点,"newjob":true,指定生成新job执行。

以上是我的看法建议,两种都支持就更灵活了,举例:

您说的冲突,对于父子之间是冲突的,job1和job2要么在一起执行,要么分开执行;

也不冲突,有job1、job2、job3、job4,如果两种都支持,就可以灵活分组, 如在job2设置了newjob,那么一个job执行job1,新的job执行job2、job3、job4, 如在job3设置了newjob,那么一个job执行job1、job2,新的job执行job3、job4, 甚至可以设置多个newjob。

PS:支持一种和支持两种,开发工作量应该差不多吧?

yuzd commented 4 years ago

懂你意思了,应该可以的

gitlsl commented 4 years ago

那还得考虑到 A job 分成A1 A2 A3 他们结果应该是 与 还是 或 ? 是都要成功 还是 只要一个成功了就跳到 B

yuzd commented 4 years ago

@gitlsl @xgsince

讨论下如下方案看看ok不?

job只要执行完毕 有设置Complete则走Complete 在检查 如果父job执行成功 Success有设置则走Success 如果父job执行失败(或有设置重试则重试到limit任然失败) Fail有设置则走Fail

newJob 如果为true 代表后面的子Job用新的hangfire job来执行

{
    "JobName": "job1",
    "Method": "GET",
    "ContentType": "application/json",
    "Url": "http://",
    "Headers": {},
    "Data": {},
    "Success": {
        "JobName": "job2",
        "newJob": true,
        "Method": "GET",
        "ContentType": "application/json",
        "Url": "http://",
        "Headers": {},
        "Data": {},
        "Success": {},
        "Fail": {},
        "Complete": {}
    },
    "Fail": {
        "JobName": "job3",
        "Method": "GET",
        "ContentType": "application/json",
        "Url": "http://",
        "Headers": {},
        "Data": {},
        "Success": {},
        "Fail": {},
        "Complete": {}
    },
    "Complete": {
        "JobName": "job4",
        "Method": "GET",
        "ContentType": "application/json",
        "Url": "http://",
        "Headers": {},
        "Data": {},
        "Success": {},
        "Fail": {},
        "Complete": {}
    }
}

image

xgsince commented 4 years ago

这结构完全可以,我想确认三点: 1.是否要在success里设置一个节点(比如"overrideData" : true),用来表明接收job1的结果作为参数? 2.邮件或者重试等其他功能节点,在子job里都有的吧?可以把最终完全的json发出来看看。 3.此次的更改应该不影响之前的配置方式吧,是兼容更新还是破坏更新?

期待新版本!@yuzd PS:overrideData是我随便起的。

yuzd commented 4 years ago

@gitlsl @xgsince

https://github.com/yuzd/Hangfire.HttpJob/wiki/%E5%AD%90Job%E5%8A%9F%E8%83%BD

xgsince commented 4 years ago

@yuzd

我认真地看了Wiki,单job降低了复杂度,这样挺好。 Fail节点看法:如果设置@parent@,应该传递的是报错信息,不知道我理解的对不对?这样可以把报错通过企业微信或短信发送。 既然节点是Success和Fail,标题为【Callback功能】是不是更合适。纯属强迫症,哈哈,never mind

题外话,看到@parent@占位符,忍不住发散一下: 可以实现日期参数占位符,如 @today@,@yesterday@,@tomorrow@等等等。 场景1,通常会有按日期查询的方法,例如排班信息,获取某一天的排班; 场景2,按日期处理业务,例如生成排班信息,生成某一天的排班。 如果要获取今天和明天的排班,就可以直接配置两个job,分别设置@today@和@tomorrow@完事。 而不用再新建工程包一层,暴露两个无参方法,然后再来配置两个job。

xgsince commented 4 years ago

@yuzd 请先忽略上面我的留言,突然想到一个重要问题,工具应该大多数情况通用。

问题:很多api,会catch报错进行处理,最终返回的是成功和失败,成功的时候同时返回数据。 这种情况必须要写一个方法来处理接收的结果,然后再进行下一步的调用,只能coding解决。 这种情况获得的报错,只能是404和超时。

疑问:基于上述情况,父子间传参是否还有支持的必要? 应用场景还是有的,只是比我之前的设想变窄了,只能处理简单结果返回,要么直接报错,要么直接返回结果数据。

yuzd commented 4 years ago
Fail节点看法:如果设置@parent@,应该传递的是报错信息,不知道我理解的对不对?

你的理解无误!

占位符

这个功能 我加了https://github.com/yuzd/Hangfire.HttpJob/wiki/%E3%80%90Callback%E5%8A%9F%E8%83%BD%E3%80%91

yuzd commented 4 years ago
问题:很多api,会catch报错进行处理,最终返回的是成功和失败,成功的时候同时返回数据。
这种情况必须要写一个方法来处理接收的结果,然后再进行下一步的调用,只能coding解决。
这种情况获得的报错,只能是404和超时。

不仅仅是404 请查看 https://github.com/yuzd/Hangfire.HttpJob/issues/28

yuzd commented 4 years ago

@xgsince

我加了一个表达式功能,用在了占位符功能和动态判断返回体是否成功还是失败! 请看下wiki:

https://github.com/yuzd/Hangfire.HttpJob/wiki/Callback%E5%8A%9F%E8%83%BD%7CEL%E8%A1%A8%E8%BE%BE%E5%BC%8F

看下有没有问题?

xgsince commented 4 years ago

本来想建议对结果做Validate,没好意思说,哈哈,怕挖的太深了。 我原来的想法是对返回值做关键字和值的简单匹配进行验证。

表达式语言来实现更强大,打开了我的视野,高大上,牛!

yuzd commented 4 years ago

@xgsince

因为对于http请求的返回 目前默认的是 statuscode>400认为是报错的。 但是对于很多业务上都是返回200,但是返回体里面有业务上的字段表示成功和失败。 因为是关于具体业务的,所以很多不确定性,采用了EL表达式来判断非常的灵活方便。 希望得到您更多的使用反馈!