GithubHelp home page GithubHelp logo

Comments (4)

brandur avatar brandur commented on August 25, 2024

@stevecalvert You don't need these lines:

	// Insert a transaction to run periodically
	_, err = riverClient.InsertTx(ctx, tx, job1Args, nil)
	if err != nil {
		// handle error
		fmt.Printf("Error inserting transaction for jobArg:%s, error:%s\n", job1Args.JobVal, err.Error())
	}
	tx.Commit(ctx)

It's the job of the periodic job scheduler to insert those jobs for you automatically, so you can omit any manual insertions.

To fix your problem, change your periodic job configuration to:

		PeriodicJobs: []*river.PeriodicJob{
			river.NewPeriodicJob(
				river.PeriodicInterval(30*time.Second),
				func() (river.JobArgs, *river.InsertOpts) {
					return job1Args, nil
				},
				&river.PeriodicJobOpts{RunOnStart: true},
			),
		},

Or even better, avoid the global state altogether (it may be prone to accidental mutation), and replace that with:

		PeriodicJobs: []*river.PeriodicJob{
			river.NewPeriodicJob(
				river.PeriodicInterval(30*time.Second),
				func() (river.JobArgs, *river.InsertOpts) {
					return PeriodicJobArgs{JobVal: "11112222"}, nil
				},
				&river.PeriodicJobOpts{RunOnStart: true},
			),
		},

from river.

stevecalvert avatar stevecalvert commented on August 25, 2024

Thanks, @brandur, that works well, but the reason I had the InsertTx() was that my use case is a sequence of overlapping ad-hoc "procedures" each lasting up to an hour but liable to stall/timeout midway. I was thinking to dynamically insert a periodic River job at the start of each procedure on the existing riverClient that checks for a stall every 2 mins or so, then gets deleted at the end - but the jobArgs aren't being retained.
Agree, the jobArgs shouldn't be global; they would be passed in by the caller of riverClient.InsertTx(). It sounds like I should be using a higher-level public function to start the periodic job if the InsertTx is intended to be used internally?

from river.

brandur avatar brandur commented on August 25, 2024

the existing riverClient that checks for a stall every 2 mins or so, then gets deleted at the end - but the jobArgs aren't being retained.

I just want to make sure that it's clear here that what you're running into isn't a bug in River. You seem to be expecting that if you insert a job manually with InsertTx, then when the same job kind is inserted via the periodic scheduler, it'll pull the arg values that you used on the most recent InsertTx invocation, but that's not how either of these features work.

I think the piece that you need to focus on is the PeriodicJobConstructor function in the periodic job configuration. When the job scheduler is about to insert a periodic job, it calls this function to create the args that it inserts. Like other func parameters, this can be a closure that can capture variables outside of its scope. You should be able to find some way of articulating the logic that you're looking for into your constructor. e.g.

lastJobVal := "11112222"

...

PeriodicJobs: []*river.PeriodicJob{
    river.NewPeriodicJob(
        river.PeriodicInterval(30*time.Second),
        func() (river.JobArgs, *river.InsertOpts) {
            return PeriodicJobArgs{JobVal: lastJobVal}, nil
        },
        &river.PeriodicJobOpts{RunOnStart: true},
    ),
},

from river.

stevecalvert avatar stevecalvert commented on August 25, 2024

Hi @brandur, I had a think about refactoring the PeriodicJob constructor, but I was ending up with providing a parallel mechanism to hold the jobArgs for multiple jobs which felt like it was starting to replicate the original functionality.

But I think I've found an alternative solution, which is to go back to dynamically inserting a single-shot job, perform the task in the Work() function then return with river.JobSnooze() to sleep the job for a couple of minutes, eventually returning nil when the monitoring is complete. Working this way, the jobs are rerun periodically, and the jobArgs preserved 👍

Maybe there is a solution using the PeriodicJob, but creating them at startup as per the example was not aligning with my use case. Anyway, I'm back in business, so I think this ticket can be closed. Thanks so much for your help!

from river.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.