Skip to content
Snippets Groups Projects
Verified Commit ab7c566f authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

feat: map time and duration in json context #60

parent 946e5621
No related branches found
No related tags found
No related merge requests found
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
<option name="autoReloadType" value="SELECTIVE" /> <option name="autoReloadType" value="SELECTIVE" />
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="9979eb22-471e-4f2f-b624-fd3edb5e8c6e" name="Changes" comment="" /> <list default="true" id="9979eb22-471e-4f2f-b624-fd3edb5e8c6e" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
...@@ -38,37 +40,38 @@ ...@@ -38,37 +40,38 @@
<option name="sortByType" value="true" /> <option name="sortByType" value="true" />
<option name="sortKey" value="BY_TYPE" /> <option name="sortKey" value="BY_TYPE" />
</component> </component>
<component name="PropertiesComponent">{ <component name="PropertiesComponent"><![CDATA[{
&quot;keyToString&quot;: { "keyToString": {
&quot;DefaultGoTemplateProperty&quot;: &quot;Go File&quot;, "DefaultGoTemplateProperty": "Go File",
&quot;Go Test.TestDummyRunnable in gitlab.schukai.com/oss/libraries/go/services/job-queues.executor&quot;: &quot;Debug&quot;, "Go Test.TestDummyRunnable in gitlab.schukai.com/oss/libraries/go/services/job-queues.executor": "Debug",
&quot;Go Test.TestManagerEventHandling in gitlab.schukai.com/oss/libraries/go/services/job-queues.executor&quot;: &quot;Debug&quot;, "Go Test.TestManagerEventHandling in gitlab.schukai.com/oss/libraries/go/services/job-queues.executor": "Debug",
&quot;Go Test.TestResetStats in gitlab.schukai.com/oss/libraries/go/services/job-queues.executor&quot;: &quot;Debug&quot;, "Go Test.TestResetStats in gitlab.schukai.com/oss/libraries/go/services/job-queues.executor": "Debug",
&quot;Go Test.TestRoundTrip in gitlab.schukai.com/oss/libraries/go/services/job-queues.executor&quot;: &quot;Debug&quot;, "Go Test.TestRoundTrip in gitlab.schukai.com/oss/libraries/go/services/job-queues.executor": "Debug",
&quot;Go Test.TestScheduleJob in gitlab.schukai.com/oss/libraries/go/services/job-queues.executor&quot;: &quot;Debug&quot;, "Go Test.TestScheduleJob in gitlab.schukai.com/oss/libraries/go/services/job-queues.executor": "Debug",
&quot;Go Test.TestStructure in gitlab.schukai.com/oss/libraries/go/services/job-queues.executor&quot;: &quot;Debug&quot;, "Go Test.TestStructure in gitlab.schukai.com/oss/libraries/go/services/job-queues.executor": "Debug",
&quot;Go Test.TestTimeFunctionSame in gitlab.schukai.com/oss/libraries/go/services/job-queues.executor&quot;: &quot;Debug&quot;, "Go Test.TestTimeFunctionSame in gitlab.schukai.com/oss/libraries/go/services/job-queues.executor": "Debug",
&quot;Go Test.TestWriteToDB1 in gitlab.schukai.com/oss/libraries/go/services/job-queues.executor&quot;: &quot;Debug&quot;, "Go Test.TestWriteToDB1 in gitlab.schukai.com/oss/libraries/go/services/job-queues.executor": "Debug",
&quot;Go Test.TestWriteToDB2 in gitlab.schukai.com/oss/libraries/go/services/job-queues.executor&quot;: &quot;Debug&quot;, "Go Test.TestWriteToDB2 in gitlab.schukai.com/oss/libraries/go/services/job-queues.executor": "Debug",
&quot;Go Test.TestWriteToDB4 in gitlab.schukai.com/oss/libraries/go/services/job-queues.executor&quot;: &quot;Debug&quot;, "Go Test.TestWriteToDB4 in gitlab.schukai.com/oss/libraries/go/services/job-queues.executor": "Debug",
&quot;Go Test.go test gitlab.schukai.com/oss/libraries/go/services/job-queues.executor&quot;: &quot;Debug&quot;, "Go Test.go test gitlab.schukai.com/oss/libraries/go/services/job-queues.executor": "Debug",
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;, "RunOnceActivity.ShowReadmeOnStart": "true",
&quot;RunOnceActivity.go.formatter.settings.were.checked&quot;: &quot;true&quot;, "RunOnceActivity.go.formatter.settings.were.checked": "true",
&quot;RunOnceActivity.go.migrated.go.modules.settings&quot;: &quot;true&quot;, "RunOnceActivity.go.migrated.go.modules.settings": "true",
&quot;SHARE_PROJECT_CONFIGURATION_FILES&quot;: &quot;true&quot;, "RunOnceActivity.go.modules.automatic.dependencies.download": "true",
&quot;git-widget-placeholder&quot;: &quot;master&quot;, "SHARE_PROJECT_CONFIGURATION_FILES": "true",
&quot;go.import.settings.migrated&quot;: &quot;true&quot;, "git-widget-placeholder": "master",
&quot;go.sdk.automatically.set&quot;: &quot;true&quot;, "go.import.settings.migrated": "true",
&quot;last_opened_file_path&quot;: &quot;/home/vs/workspaces/oss/go-libs/job-queues/nix/scripts&quot;, "go.sdk.automatically.set": "true",
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;, "last_opened_file_path": "/home/vs/workspaces/oss/go-libs/job-queues/nix/scripts",
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;, "node.js.detected.package.eslint": "true",
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;, "node.js.detected.package.tslint": "true",
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;, "node.js.selected.package.eslint": "(autodetect)",
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;, "node.js.selected.package.tslint": "(autodetect)",
&quot;settings.editor.selected.configurable&quot;: &quot;http.proxy&quot;, "nodejs_package_manager_path": "npm",
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot; "settings.editor.selected.configurable": "http.proxy",
"vue.rearranger.settings.migration": "true"
} }
}</component> }]]></component>
<component name="RecentsManager"> <component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS"> <key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/nix/scripts" /> <recent name="$PROJECT_DIR$/nix/scripts" />
......
...@@ -10,14 +10,14 @@ require ( ...@@ -10,14 +10,14 @@ require (
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
github.com/pkg/sftp v1.13.6 github.com/pkg/sftp v1.13.6
github.com/robfig/cron/v3 v3.0.1 github.com/robfig/cron/v3 v3.0.1
github.com/shirou/gopsutil/v3 v3.24.3 github.com/shirou/gopsutil/v3 v3.24.4
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0
go.uber.org/zap v1.27.0 go.uber.org/zap v1.27.0
golang.org/x/crypto v0.22.0 golang.org/x/crypto v0.22.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/mysql v1.5.6 gorm.io/driver/mysql v1.5.6
gorm.io/driver/sqlite v1.5.5 gorm.io/driver/sqlite v1.5.5
gorm.io/gorm v1.25.9 gorm.io/gorm v1.25.10
gotest.tools/v3 v3.5.1 gotest.tools/v3 v3.5.1
) )
...@@ -45,8 +45,8 @@ require ( ...@@ -45,8 +45,8 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/tklauser/go-sysconf v0.3.13 // indirect github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.7.0 // indirect github.com/tklauser/numcpus v0.8.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
golang.org/x/mod v0.8.0 // indirect golang.org/x/mod v0.8.0 // indirect
......
...@@ -67,8 +67,8 @@ github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt ...@@ -67,8 +67,8 @@ github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE= github.com/shirou/gopsutil/v3 v3.24.4 h1:dEHgzZXt4LMNm+oYELpzl9YCqV65Yr/6SfrvgRBtXeU=
github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg= github.com/shirou/gopsutil/v3 v3.24.4/go.mod h1:lTd2mdiOspcqLgAnr9/nGi71NkeMpWKdmhuxm9GusH8=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
...@@ -83,11 +83,11 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl ...@@ -83,11 +83,11 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4= github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU=
github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0= github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4= github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY=
github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY= github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
...@@ -138,7 +138,6 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc ...@@ -138,7 +138,6 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
...@@ -173,7 +172,7 @@ gorm.io/driver/mysql v1.5.6/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkD ...@@ -173,7 +172,7 @@ gorm.io/driver/mysql v1.5.6/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkD
gorm.io/driver/sqlite v1.5.5 h1:7MDMtUZhV065SilG62E0MquljeArQZNfJnjd9i9gx3E= gorm.io/driver/sqlite v1.5.5 h1:7MDMtUZhV065SilG62E0MquljeArQZNfJnjd9i9gx3E=
gorm.io/driver/sqlite v1.5.5/go.mod h1:6NgQ7sQWAIFsPrJJl1lSNSu2TABh0ZZ/zm5fosATavE= gorm.io/driver/sqlite v1.5.5/go.mod h1:6NgQ7sQWAIFsPrJJl1lSNSu2TABh0ZZ/zm5fosATavE=
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
gorm.io/gorm v1.25.9 h1:wct0gxZIELDk8+ZqF/MVnHLkA1rvYlBWUMv2EdsK1g8= gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s=
gorm.io/gorm v1.25.9/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
...@@ -21,9 +21,9 @@ type GenericJob interface { ...@@ -21,9 +21,9 @@ type GenericJob interface {
GetMaxRetries() uint GetMaxRetries() uint
GetRetryDelay() time.Duration GetRetryDelay() *time.Duration
GetTimeout() time.Duration GetTimeout() *time.Duration
GetPersistence() JobPersistence GetPersistence() JobPersistence
......
...@@ -38,9 +38,9 @@ type Job[T any] struct { ...@@ -38,9 +38,9 @@ type Job[T any] struct {
description string description string
priority Priority priority Priority
timeout time.Duration timeout *time.Duration
maxRetries uint maxRetries uint
RetryDelay time.Duration retryDelay *time.Duration
scheduler Scheduler scheduler Scheduler
...@@ -101,7 +101,7 @@ func (j *Job[T]) GetPersistence() JobPersistence { ...@@ -101,7 +101,7 @@ func (j *Job[T]) GetPersistence() JobPersistence {
Priority: j.priority, Priority: j.priority,
Timeout: j.timeout, Timeout: j.timeout,
MaxRetries: j.maxRetries, MaxRetries: j.maxRetries,
RetryDelay: j.RetryDelay, RetryDelay: j.retryDelay,
Dependencies: j.dependencies, Dependencies: j.dependencies,
Runnable: j.runner.GetPersistence(), Runnable: j.runner.GetPersistence(),
...@@ -314,12 +314,12 @@ func (j *Job[T]) SetTimeout(timeout time.Duration) *Job[T] { ...@@ -314,12 +314,12 @@ func (j *Job[T]) SetTimeout(timeout time.Duration) *Job[T] {
j.mu.Lock() j.mu.Lock()
defer j.mu.Unlock() defer j.mu.Unlock()
j.timeout = timeout j.timeout = &timeout
return j return j
} }
// GetTimeout returns the timeout of the job // GetTimeout returns the timeout of the job
func (j *Job[T]) GetTimeout() time.Duration { func (j *Job[T]) GetTimeout() *time.Duration {
j.mu.Lock() j.mu.Lock()
defer j.mu.Unlock() defer j.mu.Unlock()
...@@ -348,16 +348,16 @@ func (j *Job[T]) SetRetryDelay(retryDelay time.Duration) *Job[T] { ...@@ -348,16 +348,16 @@ func (j *Job[T]) SetRetryDelay(retryDelay time.Duration) *Job[T] {
j.mu.Lock() j.mu.Lock()
defer j.mu.Unlock() defer j.mu.Unlock()
j.RetryDelay = retryDelay j.retryDelay = &retryDelay
return j return j
} }
// GetRetryDelay returns the retry delay of the job // GetRetryDelay returns the retry delay of the job
func (j *Job[T]) GetRetryDelay() time.Duration { func (j *Job[T]) GetRetryDelay() *time.Duration {
j.mu.Lock() j.mu.Lock()
defer j.mu.Unlock() defer j.mu.Unlock()
return j.RetryDelay return j.retryDelay
} }
// SetDependencies sets the dependencies of the job // SetDependencies sets the dependencies of the job
......
...@@ -39,7 +39,7 @@ func TestSetPriority(t *testing.T) { ...@@ -39,7 +39,7 @@ func TestSetPriority(t *testing.T) {
func TestSetAndGetTimeout(t *testing.T) { func TestSetAndGetTimeout(t *testing.T) {
job := NewJob[ShellResult]("id1", &ShellRunnable{}) job := NewJob[ShellResult]("id1", &ShellRunnable{})
job.SetTimeout(5 * time.Minute) job.SetTimeout(5 * time.Minute)
assert.Equal(t, 5*time.Minute, job.GetTimeout()) assert.Equal(t, 5*time.Minute, *job.GetTimeout())
} }
func TestSetAndGetMaxRetries(t *testing.T) { func TestSetAndGetMaxRetries(t *testing.T) {
...@@ -57,7 +57,7 @@ func TestSetAndGetRunnable(t *testing.T) { ...@@ -57,7 +57,7 @@ func TestSetAndGetRunnable(t *testing.T) {
func TestSetAndGetRetryDelay(t *testing.T) { func TestSetAndGetRetryDelay(t *testing.T) {
job := NewJob[ShellResult]("id1", &ShellRunnable{}) job := NewJob[ShellResult]("id1", &ShellRunnable{})
job.SetRetryDelay(2 * time.Second) job.SetRetryDelay(2 * time.Second)
assert.Equal(t, 2*time.Second, job.GetRetryDelay()) assert.Equal(t, 2*time.Second, *job.GetRetryDelay())
} }
func TestSetAndGetDependencies(t *testing.T) { func TestSetAndGetDependencies(t *testing.T) {
...@@ -90,7 +90,7 @@ func TestGetPriority(t *testing.T) { ...@@ -90,7 +90,7 @@ func TestGetPriority(t *testing.T) {
func TestGetTimeout(t *testing.T) { func TestGetTimeout(t *testing.T) {
job := NewJob[ShellResult]("id2", &ShellRunnable{}) job := NewJob[ShellResult]("id2", &ShellRunnable{})
assert.Equal(t, time.Duration(0), job.GetTimeout()) assert.Nil(t, job.GetTimeout())
} }
func TestGetMaxRetries(t *testing.T) { func TestGetMaxRetries(t *testing.T) {
...@@ -100,7 +100,7 @@ func TestGetMaxRetries(t *testing.T) { ...@@ -100,7 +100,7 @@ func TestGetMaxRetries(t *testing.T) {
func TestGetRetryDelay(t *testing.T) { func TestGetRetryDelay(t *testing.T) {
job := NewJob[ShellResult]("id2", &ShellRunnable{}) job := NewJob[ShellResult]("id2", &ShellRunnable{})
assert.Equal(t, time.Duration(0), job.GetRetryDelay()) assert.Nil(t, job.GetRetryDelay())
} }
func TestGetDependencies(t *testing.T) { func TestGetDependencies(t *testing.T) {
......
...@@ -72,12 +72,14 @@ func (m *MockGenericJob) GetMaxRetries() uint { ...@@ -72,12 +72,14 @@ func (m *MockGenericJob) GetMaxRetries() uint {
return 0 return 0
} }
func (m *MockGenericJob) GetRetryDelay() time.Duration { func (m *MockGenericJob) GetRetryDelay() *time.Duration {
return 0 dur := time.Duration(0)
return &dur
} }
func (m *MockGenericJob) GetTimeout() time.Duration { func (m *MockGenericJob) GetTimeout() *time.Duration {
return 0 dur := time.Duration(0)
return &dur
} }
func (m *MockGenericJob) GetID() JobID { func (m *MockGenericJob) GetID() JobID {
......
...@@ -19,16 +19,20 @@ type JobPersistence struct { ...@@ -19,16 +19,20 @@ type JobPersistence struct {
ID JobID `yaml:"id" json:"id" gorm:"type:varchar(255);primaryKey"` ID JobID `yaml:"id" json:"id" gorm:"type:varchar(255);primaryKey"`
Description string `yaml:"description" json:"description" gorm:"column:description"` Description string `yaml:"description" json:"description" gorm:"column:description"`
Priority Priority `yaml:"priority" json:"priority" gorm:"column:priority"` Priority Priority `yaml:"priority" json:"priority" gorm:"column:priority"`
Timeout time.Duration `yaml:"timeout" json:"timeout" gorm:"column:timeout"` Timeout *time.Duration `yaml:"-" json:"-" gorm:"column:timeout"`
MaxRetries uint `yaml:"maxRetries" json:"maxRetries" gorm:"column:max_retries"` MaxRetries uint `yaml:"maxRetries" json:"maxRetries" gorm:"column:max_retries"`
RetryDelay time.Duration `yaml:"retryDelay" json:"retryDelay" gorm:"column:retry_delay"` RetryDelay *time.Duration `yaml:"-" json:"-" gorm:"column:retry_delay"`
Dependencies []JobID `yaml:"dependencies" json:"dependencies,omitempty" gorm:"column:dependencies;type:json"` Dependencies []JobID `yaml:"dependencies" json:"dependencies,omitempty" gorm:"column:dependencies;type:json"`
Runnable RunnableImport `yaml:"runnable" json:"runnable" gorm:"embedded;embeddedPrefix:runnable_"` Runnable RunnableImport `yaml:"runnable" json:"runnable" gorm:"embedded;embeddedPrefix:runnable_"`
Scheduler SchedulerPersistence `yaml:"scheduler" json:"scheduler,omitempty" gorm:"embedded;embeddedPrefix:scheduler_"` Scheduler SchedulerPersistence `yaml:"scheduler" json:"scheduler,omitempty" gorm:"embedded;embeddedPrefix:scheduler_"`
Pause bool `yaml:"pause" json:"pause" gorm:"column:pause"` Pause bool `yaml:"pause" json:"pause" gorm:"column:pause"`
PauseReason string `yaml:"pauseReason" json:"pauseReason" gorm:"column:pause_reason"` PauseReason string `yaml:"pauseReason" json:"pauseReason" gorm:"column:pause_reason"`
PauseUntil *time.Time `yaml:"pauseUntil" json:"pauseUntil" gorm:"column:pause_until"` PauseUntil *time.Time `yaml:"-" json:"-" gorm:"column:pause_until"`
TimeoutString *string `yaml:"timeout,omitempty" json:"timeout,omitempty" gorm:"-"`
RetryDelayString *string `yaml:"retryDelay,omitempty" json:"retryDelay,omitempty" gorm:"-"`
PauseUntilString *string `yaml:"pauseUntil" json:"pauseUntil,omitempty" gorm:"-"`
Logs []JobLog `gorm:"foreignKey:JobID;references:ID" json:"-" yaml:"-"` Logs []JobLog `gorm:"foreignKey:JobID;references:ID" json:"-" yaml:"-"`
Stats JobStats `gorm:"foreignKey:JobID" json:"stats" yaml:"stats"` Stats JobStats `gorm:"foreignKey:JobID" json:"stats" yaml:"stats"`
...@@ -38,39 +42,95 @@ type JobPersistence struct { ...@@ -38,39 +42,95 @@ type JobPersistence struct {
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;index" json:"-" yaml:"-"` DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;index" json:"-" yaml:"-"`
} }
// UnmarshalJSON implements the json.Unmarshaler interface. func (j *JobPersistence) MarshalJSON() ([]byte, error) {
func (jp *JobPersistence) UnmarshalJSON(data []byte) error { type Alias JobPersistence
// Anonymous struct for unmarshalling with custom time format return json.Marshal(&struct {
*Alias
TimeoutString string `json:"timeout,omitempty"`
RetryDelayString string `json:"retryDelay,omitempty"`
PauseUntilString string `json:"pauseUntil,omitempty"`
}{
Alias: (*Alias)(j),
TimeoutString: formatDuration(j.Timeout),
RetryDelayString: formatDuration(j.RetryDelay),
PauseUntilString: formatTime(j.PauseUntil),
})
}
func (j *JobPersistence) UnmarshalJSON(data []byte) error {
type Alias JobPersistence type Alias JobPersistence
aux := &struct { aux := &struct {
PauseUntil *string `json:"pauseUntil,omitempty"`
*Alias *Alias
TimeoutString *string `json:"timeout,omitempty"`
RetryDelayString *string `json:"retryDelay,omitempty"`
PauseUntilString *string `json:"pauseUntil,omitempty"`
}{ }{
Alias: (*Alias)(jp), Alias: (*Alias)(j),
} }
if err := json.Unmarshal(data, aux); err != nil {
if err := json.Unmarshal(data, &aux); err != nil {
return err return err
} }
if aux.TimeoutString != nil && *aux.TimeoutString != "" {
if aux.PauseUntil != nil { d, err := time.ParseDuration(*aux.TimeoutString)
var t time.Time if err != nil {
var err error return err
for _, format := range SupportedTimeFormats {
t, err = time.Parse(format, *aux.PauseUntil)
if err == nil {
break
}
} }
j.Timeout = &d
}
if aux.RetryDelayString != nil && *aux.RetryDelayString != "" {
d, err := time.ParseDuration(*aux.RetryDelayString)
if err != nil { if err != nil {
return err return err
} }
jp.PauseUntil = &t j.RetryDelay = &d
} }
if aux.PauseUntilString != nil && *aux.PauseUntilString != "" {
t, err := parseMultipleDateFormats(*aux.PauseUntilString, []string{
time.RFC3339, time.RFC3339Nano,
"2006-01-02T15:04:05",
"2006-01-02T15:04:05.999999999",
"2006-01-02T15:04:05Z07:00",
"2006-01-02T15:04:05",
"2006-01-02T15:04",
"2006-01-02T15",
"2006-01-02T",
"2006-01-02",
})
if err != nil {
return err
}
j.PauseUntil = &t
}
return nil return nil
} }
func parseMultipleDateFormats(value string, formats []string) (time.Time, error) {
var t time.Time
var err error
for _, format := range formats {
t, err = time.Parse(format, value)
if err == nil {
return t, nil
}
}
return t, fmt.Errorf("date string '%s' does not match any known format", value)
}
func formatDuration(d *time.Duration) string {
if d != nil {
return d.String()
}
return ""
}
func formatTime(t *time.Time) string {
if t != nil {
return t.Format(time.RFC3339)
}
return ""
}
func (jp JobPersistence) GetLogs() []JobLog { func (jp JobPersistence) GetLogs() []JobLog {
return jp.Logs return jp.Logs
} }
...@@ -96,7 +156,7 @@ func (jp JobPersistence) GetPriority() Priority { ...@@ -96,7 +156,7 @@ func (jp JobPersistence) GetPriority() Priority {
} }
func (jp JobPersistence) GetTimeout() time.Duration { func (jp JobPersistence) GetTimeout() time.Duration {
return jp.Timeout return *jp.Timeout
} }
func (JobPersistence) TableName() string { func (JobPersistence) TableName() string {
...@@ -182,13 +242,14 @@ func ReadFromGORM(db *gorm.DB) ([]JobPersistence, error) { ...@@ -182,13 +242,14 @@ func ReadFromGORM(db *gorm.DB) ([]JobPersistence, error) {
} }
func CreateGenericJobFromPersistence[T any](jobImport JobPersistence, runner Runnable[T]) GenericJob { func CreateGenericJobFromPersistence[T any](jobImport JobPersistence, runner Runnable[T]) GenericJob {
return &Job[T]{ return &Job[T]{
id: jobImport.ID, id: jobImport.ID,
description: jobImport.Description, description: jobImport.Description,
priority: jobImport.Priority, priority: jobImport.Priority,
timeout: jobImport.Timeout, timeout: jobImport.Timeout,
maxRetries: jobImport.MaxRetries, maxRetries: jobImport.MaxRetries,
RetryDelay: jobImport.RetryDelay, retryDelay: jobImport.RetryDelay,
dependencies: jobImport.Dependencies, dependencies: jobImport.Dependencies,
pause: jobImport.Pause, pause: jobImport.Pause,
pauseReason: jobImport.PauseReason, pauseReason: jobImport.PauseReason,
......
...@@ -14,6 +14,10 @@ import ( ...@@ -14,6 +14,10 @@ import (
) )
func TestCreateJobAndSchedulerFromInput(t *testing.T) { func TestCreateJobAndSchedulerFromInput(t *testing.T) {
time10s := 10 * time.Second
time2s := 5 * time.Minute
tests := []struct { tests := []struct {
name string name string
input JobPersistence input JobPersistence
...@@ -26,9 +30,9 @@ func TestCreateJobAndSchedulerFromInput(t *testing.T) { ...@@ -26,9 +30,9 @@ func TestCreateJobAndSchedulerFromInput(t *testing.T) {
input: JobPersistence{ input: JobPersistence{
ID: "1", ID: "1",
Priority: 1, Priority: 1,
Timeout: 10 * time.Second, Timeout: &time10s,
MaxRetries: 3, MaxRetries: 3,
RetryDelay: 2 * time.Second, RetryDelay: &time2s,
Runnable: RunnableImport{ Runnable: RunnableImport{
Type: "Shell", Type: "Shell",
Data: map[string]any{"ScriptPath": "script.sh"}, Data: map[string]any{"ScriptPath": "script.sh"},
...@@ -89,6 +93,86 @@ func TestCreateJobAndSchedulerFromInput(t *testing.T) { ...@@ -89,6 +93,86 @@ func TestCreateJobAndSchedulerFromInput(t *testing.T) {
} }
} }
func TestJobPersistence_MarshalUnmarshalJSON(t *testing.T) {
timeRef := time.Now().Round(time.Second) // Runden, um Genauigkeitsverlust zu vermeiden
timeRefString := timeRef.Format(time.RFC3339)
time5m := 5 * time.Minute
time10s := 10 * time.Second
time30s := 30 * time.Second
time1Hour := 1 * time.Hour
time10sString := "10s"
time30sString := "30s"
time5m0sString := "5m0s"
time1h0m0sString := "1h0m0s"
emptyString := ""
tests := []struct {
name string
job JobPersistence
expected string
}{
{
name: "All fields present",
job: JobPersistence{
Timeout: &time5m,
RetryDelay: &time10s,
PauseUntil: &timeRef,
TimeoutString: &time5m0sString,
RetryDelayString: &time10sString,
PauseUntilString: &timeRefString,
},
expected: ` {"id":"","description":"","priority":0,"maxRetries":0,"runnable":{"type":""},"scheduler":{"type":""},"pause":false,"pauseReason":"","timeout":"5m0s","retryDelay":"10s","pauseUntil":"` + timeRefString + `","stats":{"jobId":"","runCount":0,"successCount":0,"errorCount":0,"timeMetrics":{"avg":0,"max":0,"min":0,"total":0},"createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z"},"createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z"}`,
},
{
name: "Nil pauseUntil",
job: JobPersistence{
Timeout: &time1Hour,
RetryDelay: &time30s,
PauseUntil: nil,
TimeoutString: &time1h0m0sString,
RetryDelayString: &time30sString,
PauseUntilString: &emptyString,
},
expected: `{"id":"","description":"","priority":0,"maxRetries":0,"runnable":{"type":""},"scheduler":{"type":""},"pause":false,"pauseReason":"","timeout":"1h0m0s","retryDelay":"30s","pauseUntil":"","stats":{"jobId":"","runCount":0,"successCount":0,"errorCount":0,"timeMetrics":{"avg":0,"max":0,"min":0,"total":0},"createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z"},"createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z"}`,
},
{
name: "Nil timeout and retryDelay",
job: JobPersistence{
Timeout: nil,
RetryDelay: nil,
PauseUntil: nil,
TimeoutString: &emptyString,
RetryDelayString: &emptyString,
PauseUntilString: &emptyString,
},
expected: `{"id":"","description":"","priority":0,"maxRetries":0,"runnable":{"type":""},"scheduler":{"type":""},"pause":false,"pauseReason":"","timeout":"","retryDelay":"","pauseUntil":"","stats":{"jobId":"","runCount":0,"successCount":0,"errorCount":0,"timeMetrics":{"avg":0,"max":0,"min":0,"total":0},"createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z"},"createdAt":"0001-01-01T00:00:00Z","updatedAt":"0001-01-01T00:00:00Z"}`,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
// MarshalJSON testen
data, err := json.Marshal(tc.job)
assert.NoError(t, err)
assert.JSONEq(t, tc.expected, string(data))
var job JobPersistence
err = json.Unmarshal(data, &job)
assert.NoError(t, err)
assert.Equal(t, tc.job.Timeout, job.Timeout)
assert.Equal(t, tc.job.RetryDelay, job.RetryDelay)
if tc.job.PauseUntil != nil {
assert.Equal(t, *tc.job.PauseUntil, *job.PauseUntil)
} else {
assert.Nil(t, job.PauseUntil)
}
})
}
}
func TestReadJsonFile(t *testing.T) { func TestReadJsonFile(t *testing.T) {
testContent := `[{"id": "1", "priority": 1}]` testContent := `[{"id": "1", "priority": 1}]`
tempFile, err := ioutil.TempFile("", "test.json") tempFile, err := ioutil.TempFile("", "test.json")
......
...@@ -208,8 +208,8 @@ func (w *LocalWorker) run(jobChannel chan GenericJob, stopChan chan bool, cancel ...@@ -208,8 +208,8 @@ func (w *LocalWorker) run(jobChannel chan GenericJob, stopChan chan bool, cancel
var cancel context.CancelFunc var cancel context.CancelFunc
timeout := job.GetTimeout() timeout := job.GetTimeout()
if timeout > 0 { if timeout != nil && *timeout > 0 {
ctx, cancel = context.WithTimeout(ctx, timeout) ctx, cancel = context.WithTimeout(ctx, *timeout)
} }
Info("Executing job on worker thread", "worker", w.ID, "thread_id", workerThreadID, "job_id", job.GetID()) Info("Executing job on worker thread", "worker", w.ID, "thread_id", workerThreadID, "job_id", job.GetID())
...@@ -230,8 +230,8 @@ func (w *LocalWorker) run(jobChannel chan GenericJob, stopChan chan bool, cancel ...@@ -230,8 +230,8 @@ func (w *LocalWorker) run(jobChannel chan GenericJob, stopChan chan bool, cancel
break break
} }
if retryDelay > 0 { if retryDelay != nil && *retryDelay > 0 {
time.Sleep(retryDelay) time.Sleep(*retryDelay)
} }
retries-- retries--
......
...@@ -47,12 +47,12 @@ func (j DummyJob) GetMaxRetries() uint { ...@@ -47,12 +47,12 @@ func (j DummyJob) GetMaxRetries() uint {
return 0 return 0
} }
func (j DummyJob) GetRetryDelay() time.Duration { func (j DummyJob) GetRetryDelay() *time.Duration {
return 0 return nil
} }
func (j DummyJob) GetTimeout() time.Duration { func (j DummyJob) GetTimeout() *time.Duration {
return 0 return nil
} }
func (j DummyJob) Execute(_ context.Context) (RunGenericResult, error) { func (j DummyJob) Execute(_ context.Context) (RunGenericResult, error) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment