Skip to content

[FEATURE] - Allow Disabling Global Locker At Job Level #808

@seinshah

Description

@seinshah

Is your feature request related to a problem? Please describe

There are occasions that we want our general schedulers to have a locking mechanism and instances of scheduler run only one job across all instances for all the defined job except some of them. In other words, let a specific job to be scheduled by all the scheduler across different instances.

Describe the solution you'd like

1. Edit WithDistributedJobLocker

gocron/job.go

Lines 552 to 560 in c180381

func WithDistributedJobLocker(locker Locker) JobOption {
return func(j *internalJob, _ time.Time) error {
if locker == nil {
return ErrWithDistributedJobLockerNil
}
j.locker = locker
return nil
}
}

func WithDistributedJobLocker(locker Locker) JobOption {
	return func(j *internalJob, _ time.Time) error {
		if locker == nil {
			j.disableGlobalLocker = true // new struct property
		} else {
		       j.locker = locker
                }
		return nil
	}
}

2. Update executor.runJob to respect the above

gocron/executor.go

Lines 373 to 391 in c180381

} else if j.locker != nil {
lock, err := j.locker.Lock(j.ctx, j.name)
if err != nil {
_ = callJobFuncWithParams(j.afterLockError, j.id, j.name, err)
e.sendOutForRescheduling(&jIn)
e.incrementJobCounter(j, Skip)
return
}
defer func() { _ = lock.Unlock(j.ctx) }()
} else if e.locker != nil {
lock, err := e.locker.Lock(j.ctx, j.name)
if err != nil {
_ = callJobFuncWithParams(j.afterLockError, j.id, j.name, err)
e.sendOutForRescheduling(&jIn)
e.incrementJobCounter(j, Skip)
return
}
defer func() { _ = lock.Unlock(j.ctx) }()
}

The last else would be:

...
else if e.locker != nil && !j.disableGlobalLocker {
        ...
}

Describe alternatives you've considered

The only way I have came to is to implement a custom locker on my side and drop using the locking mechanism of gocron as these methods and functions are not part of the package's public API.

Additional context

I'd be happy to open a PR and address this enhancement.
This feature would allow to run some of our jobs in batch mode by all the instance (and let the job itself decide how they want to divide and conquer if necessary) and some of our jobs only to be run by one instance at each point in time.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions