bamzi / jobrunner

Framework for performing work asynchronously, outside of the request flow
MIT License
1.04k stars 99 forks source link

Name not displayed in status page even when explicitly set #8

Closed wwsean08 closed 6 years ago

wwsean08 commented 6 years ago

I am currently trying to use jobrunner to setup scheduled pulls of data, I want to set the name of the job based on what is being pulled by that job explicitly. Below is a breakdown of my code and the json that I get back when checking the status:

func (ud *UserData) Schedule(interval time.Duration, jobName string) {
    regenerate_data := jobrunner.New(ud)
    regenerate_data.Name = "Test"
    ud.job = regenerate_data
    jobrunner.Every(interval, regenerate_data)
    // Initial run
    jobrunner.Now(regenerate_data)
}
{
    "jobrunner": [
        {
            "Id": 1,
            "JobRunner": {
                "Name": "",
                "Status": "IDLE",
                "Latency": "157.331µs"
            },
            "Next": "2017-09-01T11:28:38-07:00",
            "Prev": "2017-09-01T11:27:38-07:00"
        }
    ]
}

I'd expect that the name is displayed no matter what. For testing purposes I had the job log out the name and verify that the job has it set properly:

func (ud *UserData) Run() {
    log.Debugf("Starting job %s", ud.job.Name)
    log.Info(ud.job.Name)
    return
}

Which gave me this log output showing that the name is in fact set:

{"level":"info","msg":"Test","time":"2017-09-01T11:26:38.957340798-07:00"}
{"level":"info","msg":"Test","time":"2017-09-01T11:27:38.000367709-07:00"}
bamzi commented 6 years ago

What you want to do is a bit backwards. You can have a struct type named "Test" and use that since JobRunner basically takes the name of the struct. It'll keep you code clean and sane.

// obviously "Test" is not the best name option
type Test struct {}
func (t Test) Run(){
   // do something
}

But if you really insist this is how to do it:

 func (ud *UserData) Schedule(interval time.Duration, jobName string) {
    regenerate_data := jobrunner.New(ud) 
    regenerate_data.Name = "Test"
        // use an undocumented function to bypass name allocation
    jobrunner.MainCron.Schedule(cron.Every(interval), regenerate_data) 

        ud.job = regenerate_data  // not sure what this does, maybe a repeat of above cron job
    // Initial run
    jobrunner.Now(regenerate_data)
}
wwsean08 commented 6 years ago

Thanks for the help, I was just using test as an example. The reason i want to name them like this is that i'm going to have multiple jobs that use the same interface/struct, the only difference is how often and what they pull which is all configurable which is why I wanted to name them like this.

And the reason i saved the job off into the ud struct is so that i can include information like how long it took in debug output each run (when debug is enabled) :)

bamzi commented 6 years ago

Oh I see ... Maybe another solution is adding exportable attributes to the primary struct type and then using Switch function based on different Names.

type ExampleJob struct {
   Name string
}

func (e ExampleJob) Run() {
    switch e.Name {
    case "Test":
          // do something
    default: 
         // do something else
   }
}

and then you can simply post a new cron job from any where, like so:

jobrunner.Every(interval, ExampleJob{Name:"Test"})

I'll keep this issue closed since this conversation is outside of the original scope