Skip to content

Commit 2c08083

Browse files
authored
issue-677: support task creation with variadic args (#755)
1 parent 63a6458 commit 2c08083

File tree

2 files changed

+78
-17
lines changed

2 files changed

+78
-17
lines changed

scheduler.go

+53-17
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,57 @@ func (s *scheduler) NewJob(jobDefinition JobDefinition, task Task, options ...Jo
535535
return s.addOrUpdateJob(uuid.Nil, jobDefinition, task, options)
536536
}
537537

538+
func (s *scheduler) verifyVariadic(taskFunc reflect.Value, tsk task, variadicStart int) error {
539+
if err := s.verifyNonVariadic(taskFunc, tsk, variadicStart); err != nil {
540+
return err
541+
}
542+
parameterType := taskFunc.Type().In(variadicStart).Elem().Kind()
543+
if parameterType == reflect.Interface || parameterType == reflect.Pointer {
544+
parameterType = reflect.Indirect(reflect.ValueOf(taskFunc.Type().In(variadicStart))).Kind()
545+
}
546+
547+
for i := variadicStart; i < len(tsk.parameters); i++ {
548+
argumentType := reflect.TypeOf(tsk.parameters[i]).Kind()
549+
if argumentType == reflect.Interface || argumentType == reflect.Pointer {
550+
argumentType = reflect.TypeOf(tsk.parameters[i]).Elem().Kind()
551+
}
552+
if argumentType != parameterType {
553+
return ErrNewJobWrongTypeOfParameters
554+
}
555+
}
556+
return nil
557+
}
558+
559+
func (s *scheduler) verifyNonVariadic(taskFunc reflect.Value, tsk task, length int) error {
560+
for i := 0; i < length; i++ {
561+
t1 := reflect.TypeOf(tsk.parameters[i]).Kind()
562+
if t1 == reflect.Interface || t1 == reflect.Pointer {
563+
t1 = reflect.TypeOf(tsk.parameters[i]).Elem().Kind()
564+
}
565+
t2 := reflect.New(taskFunc.Type().In(i)).Elem().Kind()
566+
if t2 == reflect.Interface || t2 == reflect.Pointer {
567+
t2 = reflect.Indirect(reflect.ValueOf(taskFunc.Type().In(i))).Kind()
568+
}
569+
if t1 != t2 {
570+
return ErrNewJobWrongTypeOfParameters
571+
}
572+
}
573+
return nil
574+
}
575+
576+
func (s *scheduler) verifyParameterType(taskFunc reflect.Value, tsk task) error {
577+
isVariadic := taskFunc.Type().IsVariadic()
578+
if isVariadic {
579+
variadicStart := taskFunc.Type().NumIn() - 1
580+
return s.verifyVariadic(taskFunc, tsk, variadicStart)
581+
}
582+
expectedParameterLength := taskFunc.Type().NumIn()
583+
if len(tsk.parameters) != expectedParameterLength {
584+
return ErrNewJobWrongNumberOfParameters
585+
}
586+
return s.verifyNonVariadic(taskFunc, tsk, expectedParameterLength)
587+
}
588+
538589
func (s *scheduler) addOrUpdateJob(id uuid.UUID, definition JobDefinition, taskWrapper Task, options []JobOption) (Job, error) {
539590
j := internalJob{}
540591
if id == uuid.Nil {
@@ -569,23 +620,8 @@ func (s *scheduler) addOrUpdateJob(id uuid.UUID, definition JobDefinition, taskW
569620
return nil, ErrNewJobTaskNotFunc
570621
}
571622

572-
expectedParameterLength := taskFunc.Type().NumIn()
573-
if len(tsk.parameters) != expectedParameterLength {
574-
return nil, ErrNewJobWrongNumberOfParameters
575-
}
576-
577-
for i := 0; i < expectedParameterLength; i++ {
578-
t1 := reflect.TypeOf(tsk.parameters[i]).Kind()
579-
if t1 == reflect.Interface || t1 == reflect.Pointer {
580-
t1 = reflect.TypeOf(tsk.parameters[i]).Elem().Kind()
581-
}
582-
t2 := reflect.New(taskFunc.Type().In(i)).Elem().Kind()
583-
if t2 == reflect.Interface || t2 == reflect.Pointer {
584-
t2 = reflect.Indirect(reflect.ValueOf(taskFunc.Type().In(i))).Kind()
585-
}
586-
if t1 != t2 {
587-
return nil, ErrNewJobWrongTypeOfParameters
588-
}
623+
if err := s.verifyParameterType(taskFunc, tsk); err != nil {
624+
return nil, err
589625
}
590626

591627
j.name = runtime.FuncForPC(taskFunc.Pointer()).Name()

scheduler_test.go

+25
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,31 @@ func TestScheduler_NewJobTask(t *testing.T) {
899899
NewTask(&testFuncWithParams, "one", "two"),
900900
nil,
901901
},
902+
{
903+
"parameter type does not match - different argument types against variadic parameters",
904+
NewTask(func(args ...string) {}, "one", 2),
905+
ErrNewJobWrongTypeOfParameters,
906+
},
907+
{
908+
"all good string - variadic",
909+
NewTask(func(args ...string) {}, "one", "two"),
910+
nil,
911+
},
912+
{
913+
"all good mixed variadic",
914+
NewTask(func(arg int, args ...string) {}, 1, "one", "two"),
915+
nil,
916+
},
917+
{
918+
"all good struct - variadic",
919+
NewTask(func(args ...interface{}) {}, struct{}{}),
920+
nil,
921+
},
922+
{
923+
"all good no arguments passed in - variadic",
924+
NewTask(func(args ...interface{}) {}),
925+
nil,
926+
},
902927
}
903928

904929
for _, tt := range tests {

0 commit comments

Comments
 (0)