nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: go-co-op/gocron
Pull request #573 (2023-09-21 02:05:42)

fix removing a job not stopping with limit mode
### What does this do?
before running a job in the limit mode runner, we need to check that the context isn't cancelled. If it is, obviously don't run the job

### Which issue(s) does this PR fix/relate to?
<!--- Put `Resolves #XXX` here to auto-close the issue that your PR fixes (if such) --->


### List any changes that modify/break current functionality


### Have you included tests for your changes?


### Did you document any new/modified functionality?

- [ ] Updated `example_test.go`
- [ ] Updated `README.md`

### Notes



Patch:
diff --git a/executor.go b/executor.go
index 8dea17c..894468c 100644
--- a/executor.go
+++ b/executor.go
@@ -128,7 +128,11 @@ func (e *executor) limitModeRunner() {
 			return
 		case jf := <-e.limitModeQueue:
 			if !e.stopped.Load() {
-				e.runJob(jf)
+				select {
+				case <-jf.ctx.Done():
+				default:
+					e.runJob(jf)
+				}
 			}
 		}
 	}


Test patch:
diff --git a/scheduler_test.go b/scheduler_test.go
index 91b5be5..d94b6c0 100644
--- a/scheduler_test.go
+++ b/scheduler_test.go
@@ -1605,10 +1605,10 @@ func TestScheduler_SetMaxConcurrentJobs(t *testing.T) {
 		f                 func()
 	}{
 		// Expecting a total of 4 job runs:
-		// 0ms - 2 jobs are run, the 3rd job hits the limit and is skipped
-		// 100ms - job 1 hits the limit and is skipped
-		// 200ms - job 1 & 2 run
-		// 300ms - jobs 1 & 3 hit the limit and are skipped
+		// 0ms - 2 jobs are run, 1 is skipped
+		// 100ms - 3 jobs hit the limit and are skipped
+		// 200ms - 2 jobs are run, 1 is skipped
+		// 300ms - 3 jobs hit the limit and are skipped
 		{
 			"reschedule mode", 2, RescheduleMode, 4, false,
 			func() {
@@ -1616,6 +1616,13 @@ func TestScheduler_SetMaxConcurrentJobs(t *testing.T) {
 				time.Sleep(200 * time.Millisecond)
 			},
 		},
+		{
+			"reschedule mode with job removal", 2, RescheduleMode, 4, true,
+			func() {
+				semaphore <- true
+				time.Sleep(200 * time.Millisecond)
+			},
+		},
 
 		// Expecting a total of 8 job runs. The exact order of jobs may vary, for example:
 		// 0ms - jobs 2 & 3 run, job 1 hits the limit and waits
@@ -1648,10 +1655,10 @@ func TestScheduler_SetMaxConcurrentJobs(t *testing.T) {
 			j1, err := s.Every("100ms").Do(tc.f)
 			require.NoError(t, err)
 
-			j2, err := s.Every("200ms").Do(tc.f)
+			j2, err := s.Every("100ms").Do(tc.f)
 			require.NoError(t, err)
 
-			j3, err := s.Every("300ms").Do(tc.f)
+			j3, err := s.Every("100ms").Do(tc.f)
 			require.NoError(t, err)
 
 			s.StartAsync()
@@ -1682,13 +1689,13 @@ func TestScheduler_SetMaxConcurrentJobs(t *testing.T) {
 			for time.Now().Before(now.Add(200 * time.Millisecond)) {
 				select {
 				case <-semaphore:
-					counter++
+					t.Error("received a job run after jobs were removed or scheduler stopeed")
 				default:
 				}
 			}
 
-			assert.GreaterOrEqual(t, counter, tc.expectedRuns-2)
-			assert.LessOrEqual(t, counter, tc.expectedRuns+2)
+			assert.GreaterOrEqual(t, counter, tc.expectedRuns)
+			assert.LessOrEqual(t, counter, tc.expectedRuns)
 
 			if tc.removeJobs {
 				s.Stop()
Repository: go-co-op/gocron
Pull request #628 (2023-12-07 22:30:14)

month first weekday bug
### What does this do?
Fixes issue #627 

### List any changes that modify/break current functionality
None

### Have you included tests for your changes?
Added a test case



Patch:
diff --git a/scheduler.go b/scheduler.go
index f51e0bd..e681fbe 100644
--- a/scheduler.go
+++ b/scheduler.go
@@ -828,7 +828,7 @@ func (s *Scheduler) MonthFirstWeekday(weekday time.Weekday) *Scheduler {
 		return s.Cron(fmt.Sprintf("0 0 %d %d %d", day, month, weekday))
 	}
 
-	return s.Cron(fmt.Sprintf("0 0 %d %d %d", day, month+1, weekday))
+	return s.Cron(fmt.Sprintf("0 0 %d %d %d", day, (month+1)%12, weekday))
 }
 
 // LimitRunsTo limits the number of executions of this job to n.


Test patch:
diff --git a/scheduler_test.go b/scheduler_test.go
index 9edfbd8..14485a5 100644
--- a/scheduler_test.go
+++ b/scheduler_test.go
@@ -2263,6 +2263,11 @@ func TestScheduler_EveryMonthFirstWeekday(t *testing.T) {
 			expected: time.Date(2022, time.March, 7, 0, 0, 0, 0, time.UTC),
 			weekday:  time.Monday,
 		},
+		{
+			current:  time.Date(2022, time.December, 7, 0, 0, 0, 0, time.UTC),
+			expected: time.Date(2023, time.January, 2, 0, 0, 0, 0, time.UTC),
+			weekday:  time.Monday,
+		},
 	}
 
 	for _, tc := range testCases {
Repository: go-co-op/gocron
Pull request #749 (2024-07-03 14:11:37)

issue-747: Provide more details of ErrPanicRecovered
### What does this do?
This PR provides more details of ErrPanicRecovered by including the recoverData with it. 

### Which issue(s) does this PR fix/relate to?
<!--- Put `Resolves #XXX` here to auto-close the issue that your PR fixes (if such) --->
It is related to #747 and should resolve that issue.

### List any changes that modify/break current functionality


### Have you included tests for your changes?
I have updated `job_test.go` based on my changes

### Did you document any new/modified functionality?

- [x] Updated `job_test.go`

### Notes



Patch:
diff --git a/executor.go b/executor.go
index d4beea8..f366197 100644
--- a/executor.go
+++ b/executor.go
@@ -2,6 +2,7 @@ package gocron
 
 import (
 	"context"
+	"fmt"
 	"strconv"
 	"sync"
 	"time"
@@ -387,7 +388,7 @@ func (e *executor) callJobWithRecover(j internalJob) (err error) {
 			_ = callJobFuncWithParams(j.afterJobRunsWithPanic, j.id, j.name, recoverData)
 
 			// if panic is occurred, we should return an error
-			err = ErrPanicRecovered
+			err = fmt.Errorf("%w from %v", ErrPanicRecovered, recoverData)
 		}
 	}()
 


Test patch:
diff --git a/job_test.go b/job_test.go
index 2b97375..d9076ee 100644
--- a/job_test.go
+++ b/job_test.go
@@ -646,6 +646,7 @@ func TestJob_NextRuns(t *testing.T) {
 
 func TestJob_PanicOccurred(t *testing.T) {
 	gotCh := make(chan any)
+	errCh := make(chan error)
 	s := newTestScheduler(t)
 	_, err := s.NewJob(
 		DurationJob(10*time.Millisecond),
@@ -656,6 +657,8 @@ func TestJob_PanicOccurred(t *testing.T) {
 		WithEventListeners(
 			AfterJobRunsWithPanic(func(_ uuid.UUID, _ string, recoverData any) {
 				gotCh <- recoverData
+			}), AfterJobRunsWithError(func(_ uuid.UUID, _ string, err error) {
+				errCh <- err
 			}),
 		),
 	)
@@ -665,6 +668,11 @@ func TestJob_PanicOccurred(t *testing.T) {
 	got := <-gotCh
 	require.EqualError(t, got.(error), "runtime error: integer divide by zero")
 
+	err = <-errCh
+	require.ErrorIs(t, err, ErrPanicRecovered)
+	require.EqualError(t, err, "gocron: panic recovered from runtime error: integer divide by zero")
+
 	require.NoError(t, s.Shutdown())
 	close(gotCh)
+	close(errCh)
 }
Repository: go-co-op/gocron
Pull request #825 (2025-02-06 13:06:38)

fix scheduler restart
### What does this do?

There is an issue introduced by https://github.com/go-co-op/gocron/pull/819

Steps to reproduce:
1. use a job function starts with ctx and do not pass an ctx
2. stop the scheduler by running .StopJobs()
3. start the scheduler by running .Start()
4. the job function does not work properly since ctx is already cancelled

This pr fix it by updating the ctx after job is stopped

### Which issue(s) does this PR fix/relate to?

related to https://github.com/go-co-op/gocron/pull/819

### List any changes that modify/break current functionality


### Have you included tests for your changes?
yes

### Did you document any new/modified functionality?

- [ ] Updated `example_test.go`
- [ ] Updated `README.md`

### Notes



Patch:
diff --git a/scheduler.go b/scheduler.go
index 7b3e72b..fd8fac2 100644
--- a/scheduler.go
+++ b/scheduler.go
@@ -238,11 +238,8 @@ func (s *scheduler) stopScheduler() {
 	for _, j := range s.jobs {
 		j.stop()
 	}
-	for id, j := range s.jobs {
+	for _, j := range s.jobs {
 		<-j.ctx.Done()
-
-		j.ctx, j.cancel = context.WithCancel(s.shutdownCtx)
-		s.jobs[id] = j
 	}
 	var err error
 	if s.started {
@@ -254,6 +251,21 @@ func (s *scheduler) stopScheduler() {
 			err = ErrStopExecutorTimedOut
 		}
 	}
+	for id, j := range s.jobs {
+		oldCtx := j.ctx
+		if j.parentCtx == nil {
+			j.parentCtx = s.shutdownCtx
+		}
+		j.ctx, j.cancel = context.WithCancel(j.parentCtx)
+
+		// also replace the old context with the new one in the parameters
+		if len(j.parameters) > 0 && j.parameters[0] == oldCtx {
+			j.parameters[0] = j.ctx
+		}
+
+		s.jobs[id] = j
+	}
+
 	s.stopErrCh <- err
 	s.started = false
 	s.logger.Debug("gocron: scheduler stopped")


Test patch:
diff --git a/scheduler_test.go b/scheduler_test.go
index b9c591b..4fc7549 100644
--- a/scheduler_test.go
+++ b/scheduler_test.go
@@ -467,6 +467,55 @@ func TestScheduler_StopLongRunningJobs(t *testing.T) {
 	})
 }
 
+func TestScheduler_StopAndStartLongRunningJobs(t *testing.T) {
+	t.Run("start, run job, stop jobs before job is completed", func(t *testing.T) {
+		s := newTestScheduler(t,
+			WithStopTimeout(50*time.Millisecond),
+		)
+
+		restart := false
+		restartP := &restart
+
+		_, err := s.NewJob(
+			DurationJob(
+				50*time.Millisecond,
+			),
+			NewTask(
+				func(ctx context.Context) {
+					select {
+					case <-ctx.Done():
+						if *restartP {
+							t.Fatal("job should not been canceled after restart")
+						}
+					case <-time.After(100 * time.Millisecond):
+						if !*restartP {
+							t.Fatal("job can not been canceled")
+						}
+
+					}
+				},
+			),
+			WithStartAt(
+				WithStartImmediately(),
+			),
+			WithSingletonMode(LimitModeReschedule),
+		)
+		require.NoError(t, err)
+
+		s.Start()
+
+		time.Sleep(20 * time.Millisecond)
+		// the running job is canceled, no unexpected timeout error
+		require.NoError(t, s.StopJobs())
+
+		*restartP = true
+
+		s.Start()
+
+		time.Sleep(200 * time.Millisecond)
+	})
+}
+
 func TestScheduler_Shutdown(t *testing.T) {
 	defer verifyNoGoroutineLeaks(t)
Repository: go-delve/delve
Pull request #2184 (2020-09-28 09:48:48)

service/dap: make interface variable to dap.Variable conversion more readable
- Add underlying type.
- Consider "collapsing" data level.



Patch:
diff --git a/service/dap/server.go b/service/dap/server.go
index 8c9dc341..62dd14d9 100644
--- a/service/dap/server.go
+++ b/service/dap/server.go
@@ -962,7 +962,21 @@ func (s *Server) convertVariable(v *proc.Variable) (value string, variablesRefer
 		} else if len(v.Children) == 0 || v.Children[0].Kind == reflect.Invalid && v.Children[0].Addr == 0 {
 			value = "nil <" + typeName + ">"
 		} else {
-			value = "<" + typeName + ">"
+			value = "<" + typeName + "(" + v.Children[0].TypeString() + ")" + ">"
+			// TODO(polina): should we remove one level of indirection and skip "data"?
+			// Then we will have:
+			// Before:
+			//   i: <interface{}(int)>
+			//      data: 123
+			// After:
+			//   i: <interface{}(int)> 123
+			// Before:
+			//   i: <interface{}(main.MyStruct)>
+			//      data: <main.MyStruct>
+			//         field1: ...
+			// After:
+			//   i: <interface{}(main.MyStruct)>
+			//      field1: ...
 			variablesReference = s.variableHandles.create(v)
 		}
 	case reflect.Complex64, reflect.Complex128:


Test patch:
diff --git a/service/dap/server_test.go b/service/dap/server_test.go
index fb870627..b2a82d04 100644
--- a/service/dap/server_test.go
+++ b/service/dap/server_test.go
@@ -909,14 +909,14 @@ func TestScopesAndVariablesRequests2(t *testing.T) {
 					expectVarExact(t, locals, -1, "fn2", "<main.functype>", noChildren)
 					// reflect.Kind == Interface
 					expectVarExact(t, locals, -1, "ifacenil", "nil <interface {}>", noChildren)
-					ref = expectVarExact(t, locals, -1, "iface2", "<interface {}>", hasChildren)
+					ref = expectVarExact(t, locals, -1, "iface2", "<interface {}(string)>", hasChildren)
 					if ref > 0 {
 						client.VariablesRequest(ref)
 						iface2 := client.ExpectVariablesResponse(t)
 						expectChildren(t, iface2, "iface2", 1)
 						expectVarExact(t, iface2, 0, "data", `"test"`, noChildren)
 					}
-					ref = expectVarExact(t, locals, -1, "iface4", "<interface {}>", hasChildren)
+					ref = expectVarExact(t, locals, -1, "iface4", "<interface {}([]go/constant.Value)>", hasChildren)
 					if ref > 0 {
 						client.VariablesRequest(ref)
 						iface4 := client.ExpectVariablesResponse(t)
@@ -926,10 +926,12 @@ func TestScopesAndVariablesRequests2(t *testing.T) {
 							client.VariablesRequest(ref)
 							iface4data := client.ExpectVariablesResponse(t)
 							expectChildren(t, iface4data, "iface4.data", 1)
-							expectVarExact(t, iface4data, 0, "[0]", "<go/constant.Value>", hasChildren)
+							expectVarExact(t, iface4data, 0, "[0]", "<go/constant.Value(go/constant.int64Val)>", hasChildren)
 
 						}
 					}
+					expectVarExact(t, locals, -1, "errnil", "nil <error>", noChildren)
+					expectVarExact(t, locals, -1, "err1", "<error(*main.astruct)>", hasChildren)
 					// reflect.Kind == Map
 					expectVarExact(t, locals, -1, "mnil", "nil <map[string]main.astruct>", noChildren)
 					ref = expectVarExact(t, locals, -1, "m2", "<map[int]*main.astruct> (length: 1)", hasChildren)