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

feat: implement core functions

parent bd62057b
Branches
Tags
No related merge requests found
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAIEA7Ct96yDKZ1toOjMigoUV+bmH/z7kSWwtyLgjEQzN0dDU88Lo0ebK
Dj2fHbo1GZnAJg77qDqIGzWMiY8oOOfiZXpj8sPvDmVoSWyAwKZhzIHigiNY9y9nW38y28
lUC/sRBe9NTRKKEyq2Nu3QAQ60kzI5cKuZzKslU7Cz+9f8iRsAAAIAKzE8bysxPG8AAAAH
c3NoLXJzYQAAAIEA7Ct96yDKZ1toOjMigoUV+bmH/z7kSWwtyLgjEQzN0dDU88Lo0ebKDj
2fHbo1GZnAJg77qDqIGzWMiY8oOOfiZXpj8sPvDmVoSWyAwKZhzIHigiNY9y9nW38y28lU
C/sRBe9NTRKKEyq2Nu3QAQ60kzI5cKuZzKslU7Cz+9f8iRsAAAADAQABAAAAgB2FUjgR4T
sKMf0UZzvpZtXQWy+MrPyAiTiNy9RVxWR0tinCM1gJgThGe507qWeJ0HrxZIOizWCZUPfg
7SYv1hybtv7uHldg1FUAUZldtOPtyVwvWMMP0lLhYkfkxLHHx2ZzL3qnG//jvx4gIWcbxJ
9C2+bDoxc/NSeo57jFHwABAAAAQCiaEiu5AAi1ZpotYpCEZXR+CgiRTDtwSOB4eM0d4rgx
mfVdTtkQqLKhGVF6wryEwEQ6Jhz9KqE89L3HO+R3LxgAAABBAPdAheySXhXIj9/PRMW2h3
a6f5DR2D2WqRdvOwIrVJli4+SzoPlDBg8ezOAQsIcz5dMqfLhB/Nd0KCXZ1Gi6+ZsAAABB
APSGl65yhFZCCud8rmY5N/W9sszfi60lnMoaVo7EAv3ksDXqPWSR1R2fWxPDFp4i1SM1pv
cI+MFN9JpfGgiDZoEAAAALdnNAYTQyMjlkNzU=
-----END OPENSSH PRIVATE KEY-----
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDsK33rIMpnW2g6MyKChRX5uYf/PuRJbC3IuCMRDM3R0NTzwujR5soOPZ8dujUZmcAmDvuoOogbNYyJjyg45+JlemPyw+8OZWhJbIDApmHMgeKCI1j3L2dbfzLbyVQL+xEF701NEooTKrY27dABDrSTMjlwq5nMqyVTsLP71/yJGw== vs@a4229d75
AuthorizedKeysCommand /nix/store/w8vm09hri2zz7yacryzzzxvsapik4ps4-coreutils-9.1/bin/cat /home/vs/workspaces/oss/go-libs/job-queues/.devenv/chroot/home/demo/.ssh/authorized_keys
AuthorizedKeysCommandUser nobody
Match User root
ChrootDirectory /home/vs/workspaces/oss/go-libs/job-queues/.devenv/chroot
ForceCommand internal-sftp
PasswordAuthentication no
PermitTunnel no
AllowAgentForwarding no
AllowTcpForwarding no
X11Forwarding no
PermitRootLogin no
AllowUsers demo root
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACBxagk6nB2R86bvLZ7aNKHsmMAVeU67fIo2Wdp+EymHTgAAAJBntrIpZ7ay
KQAAAAtzc2gtZWQyNTUxOQAAACBxagk6nB2R86bvLZ7aNKHsmMAVeU67fIo2Wdp+EymHTg
AAAEBPmQk0dpM/BVsTi3hfROLxOgq/bzv4Sef0PNoK9Ra2NnFqCTqcHZHzpu8tnto0oeyY
wBV5Trt8ijZZ2n4TKYdOAAAAC3ZzQGE0MjI5ZDc1AQI=
-----END OPENSSH PRIVATE KEY-----
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHFqCTqcHZHzpu8tnto0oeyYwBV5Trt8ijZZ2n4TKYdO vs@a4229d75
-----BEGIN OPENSSH PRIVATE KEY-----
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
xpqPwJ4sHVB+0AAAALdnNAYTQyMjlkNzU=
-----END OPENSSH PRIVATE KEY-----
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC5OnXgylqd3LJ+0aKcNAQizs+vzxN6iAUxJ2hmbkBRtSWIr0zozudAdBy1N4xbRN6UeXBWtkLBdxCfmwKlFpYTUC0SM+1nWvqkPYeWkCRB/Ey0/1M0k/Aekn/VW6h++a7hp03E3qZnDoIffi80kaBS4U1fCrpe1uvAzhMhpwS7vXyhJ/Sg04IQKKNlKxtKgGeWOwhsJx2pcKU2zSkeraVU+PS93MaDg9AuRxGMs+gOCJB/A7E+Yv9QIGtpcegtcjLPiw1+zhlBeN8th/CAeJXXjmij+QPh2CaoJ+jgc6Kk5CW8hiziJEfKPK9CqKKtOzaHcbxlc8F6XFYPESwot81fhds0zrI+9guhlp1JtXaAkL871a/QMsluG5yOr1fmAwxWyOBxxy1+e/ARk9TeyVktTie0Q2HmMhbzDk40dq85fbf5vYysJ8/04cHqCc0C6jvA99Y9y1qlx2FDmRZQEf4b5tQSlroQDIOR72eEjLx675PXYyuZxxAVkIYoGm5H2Ys= vs@a4229d75
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GoImports">
<option name="optimizeImportsOnTheFly" value="false" />
</component>
</project>
\ No newline at end of file
name: "SFTPServerInterface"
output: "./mocks"
\ No newline at end of file
package main
import (
"fmt"
jobqueue "gitlab.schukai.com/oss/libraries/go/services/job-queues.git"
)
func main() {
jq := jobqueue.NewJobs()
if jq == nil {
panic("NewJobs returned nil")
}
// Hinzufügen eines neuen Jobs
err := jq.AddJob(jobqueue.JobSpecification{
Id: "test",
Priority: 1,
}, &jobqueue.ExternalProcessRunner{
Command: "sleep",
Args: []string{"1"},
})
if err != nil {
panic(err)
}
// Abrufen aller Jobs
allJobs := jq.GetJobs()
fmt.Println("Alle Jobs:", allJobs)
// Entfernen eines Jobs
removed, err := jq.RemoveJob("test")
if err != nil {
panic(err)
}
if removed {
fmt.Println("Job wurde entfernt.")
}
}
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
zlib zlib
nodePackages.mermaid-cli nodePackages.mermaid-cli
feh feh
openssh
]; ];
...@@ -52,6 +53,52 @@ ...@@ -52,6 +53,52 @@
difftastic.enable = true; difftastic.enable = true;
scripts.run-sshd.exec = ''
set -x
cd ${config.devenv.root}/docker/sftp-server
${pkgs.docker-client}/bin/docker docker build -t jobqueue-sftp-server .
cd -
${pkgs.coreutils}/bin/chmod 700 ${config.devenv.root}/.config/temp_rsa_key
${pkgs.coreutils}/bin/chmod 700 ${config.devenv.root}/.config/temp_ed25518_key
${pkgs.coreutils}/bin/mkdir -p ${config.devenv.root}/.devenv/chroot/home/demo/.ssh
${pkgs.coreutils}/bin/cat ${config.devenv.root}/.config/demo_ssh_key.pub > ${config.devenv.root}/.devenv/chroot/home/demo/.ssh/authorized_keys
${pkgs.coreutils}/bin/chmod 700 ${config.devenv.root}/.devenv/chroot/home/demo/.ssh
${pkgs.coreutils}/bin/chmod 600 ${config.devenv.root}/.devenv/chroot/home/demo/.ssh/authorized_keys
${pkgs.coreutils}/bin/cat <<EOF > ${config.devenv.root}/.config/sshd_config
AuthorizedKeysCommand ${pkgs.coreutils}/bin/cat ${config.devenv.root}/.devenv/chroot/home/demo/.ssh/authorized_keys
AuthorizedKeysCommandUser nobody
Match User root
ChrootDirectory ${config.devenv.root}/.devenv/chroot
ForceCommand internal-sftp
PasswordAuthentication no
PermitTunnel no
AllowAgentForwarding no
AllowTcpForwarding no
X11Forwarding no
PermitRootLogin no
AllowUsers demo root
EOF
${pkgs.openssh}/bin/sshd -D -e -o \
HostKey=${config.devenv.root}/.config/temp_rsa_key \
-f ${config.devenv.root}/.config/sshd_config \
-o HostKey=${config.devenv.root}/.config/temp_ed25518_key \
-o Port=''${1:-2222} \
-o AuthorizedKeysFile=${config.devenv.root}/.devenv/chroot/home/demo/.ssh/authorized_keys \
-o PidFile=${config.devenv.root}/.devenv/sshd.pid
'';
scripts.draw-graph.exec = '' scripts.draw-graph.exec = ''
echo -e "Enter Meirmaid graph definition. ''${RED}End with Ctrl+D''${RESET}\n" echo -e "Enter Meirmaid graph definition. ''${RED}End with Ctrl+D''${RESET}\n"
diagram=$(${pkgs.gum}/bin/gum write --placeholder "Enter Meirmaid graph definition. End with Ctrl+D") diagram=$(${pkgs.gum}/bin/gum write --placeholder "Enter Meirmaid graph definition. End with Ctrl+D")
...@@ -660,4 +707,5 @@ ...@@ -660,4 +707,5 @@
printLogfileAndExit 0 printLogfileAndExit 0
''; '';
} }
package jobqueue
import "fmt"
var (
ErrCPUPercentage = fmt.Errorf("could not get CPU percentage")
ErrIntervalIsZero = fmt.Errorf("interval must not be 0")
ErrResourceLimitExceeded = fmt.Errorf("resource limit exceeded")
ErrNoRunDefined = fmt.Errorf("no runnable function defined")
ErrCycleDetected = fmt.Errorf("cycle detected")
ErrJobAlreadyExists = fmt.Errorf("job already exists")
ErrUnknownDependency = fmt.Errorf("unknown dependency")
ErrMissingDependency = fmt.Errorf("missing dependency")
ErrJobNotFound = fmt.Errorf("job not found")
ErrJobIsDependency = fmt.Errorf("job is a dependency")
ErrNotRunning = fmt.Errorf("job queue is not running")
ErrAlreadyPaused = fmt.Errorf("job queue is already paused")
ErrAlreadyStopped = fmt.Errorf("job queue is already stopped")
ErrNotPaused = fmt.Errorf("job queue is not paused")
ErrAlreadyStarted = fmt.Errorf("job queue is already started")
ErrTimeout = fmt.Errorf("job timed out")
//ErrInitializationFailed = fmt.Errorf("resource monitoring initialization failed")
)
package jobqueue
import (
"fmt"
)
var (
ErrMissingDependency = fmt.Errorf("missing dependency")
ErrCycleDetected = fmt.Errorf("cycle detected")
ErrQueueEmpty = fmt.Errorf("queue is empty")
ErrJobAlreadyExists = fmt.Errorf("job already exists")
ErrWorkerNotRunning = fmt.Errorf("worker is not running")
ErrMaxJobsReached = fmt.Errorf("maximum number of jobs reached")
ErrWorkerAlreadyRunning = fmt.Errorf("worker is already running")
ErrWorkerAlreadyAdded = fmt.Errorf("worker is already added")
ErrWorkerNotAdded = fmt.Errorf("worker is not added")
ErrNoWorkers = fmt.Errorf("no workers")
ErrWorkerAlreadyStopped = fmt.Errorf("worker is already stopped")
ErrManagerAlreadyStopped = fmt.Errorf("manager is already stopped")
ErrManagerAlreadyRunning = fmt.Errorf("manager is already running")
ErrManagerNotRunning = fmt.Errorf("manager is not running")
ErrJobNotScheduled = fmt.Errorf("job is not scheduled")
ErrCronNotInitialized = fmt.Errorf("cron is not initialized")
ErrCPUPercentage = fmt.Errorf("cpu percentage must be between 0 and 100")
ErrIntervalIsZero = fmt.Errorf("interval must be greater than 0")
ErrUnknownRunnableType = fmt.Errorf("unknown runnable type")
ErrUnknownSchedulerType = fmt.Errorf("unknown scheduler type")
ErrUnsupportedDatabaseType = fmt.Errorf("unsupported database type")
ErrUnsupportedFileOption = fmt.Errorf("unsupported file option")
ErrUnsupportedCredentialType = fmt.Errorf("unsupported credential type")
ErrUnsupportedTransferDirection = fmt.Errorf("unsupported transfer direction")
)
package jobqueue
import (
"sync"
)
type EventName string
const (
JobAdded EventName = "JobAdded"
JobRemoved EventName = "JobRemoved"
ExecuteJob EventName = "ExecuteJob"
JobReady EventName = "JobReady"
QueueJob EventName = "QueueJob"
// add more events as needed
)
type Event struct {
Name EventName
Data any
}
// EventBus is a simple event bus
type EventBus struct {
subscribers map[EventName][]chan interface{}
mu sync.RWMutex
}
// NewEventBus creates a new event bus
func NewEventBus() *EventBus {
return &EventBus{
subscribers: make(map[EventName][]chan interface{}),
}
}
// Subscribe adds a channel to the subscribers list
func (eb *EventBus) Subscribe(name EventName, ch chan interface{}) {
eb.mu.Lock()
defer eb.mu.Unlock()
if _, found := eb.subscribers[name]; !found {
eb.subscribers[name] = []chan interface{}{}
}
eb.subscribers[name] = append(eb.subscribers[name], ch)
}
// Unsubscribe removes a channel from the subscribers list
func (eb *EventBus) Unsubscribe(name EventName, ch chan interface{}) {
eb.mu.Lock()
defer eb.mu.Unlock()
if channels, found := eb.subscribers[name]; found {
for i := range channels {
if channels[i] == ch {
eb.subscribers[name] = append(channels[:i], channels[i+1:]...)
break
}
}
}
}
// Publish publishes an event to all subscribers
func (eb *EventBus) Publish(name EventName, data interface{}) {
eb.mu.RLock()
defer eb.mu.RUnlock()
if channels, found := eb.subscribers[name]; found {
for _, ch := range channels {
ch <- Event{Name: name, Data: data}
}
}
}
package jobqueue
import (
"sync"
"testing"
"time"
)
func TestSubscribeAndPublish(t *testing.T) {
eb := NewEventBus()
jobAddedCh := make(chan interface{}, 1)
eb.Subscribe(JobAdded, jobAddedCh)
jobData := "New Job Data"
eb.Publish(JobAdded, jobData)
select {
case receivedData := <-jobAddedCh:
rd := receivedData.(Event)
if rd.Data != jobData {
t.Errorf("Received data %v, want %v", receivedData, jobData)
}
case <-time.After(1 * time.Second):
t.Error("Timed out waiting for published event")
}
}
func TestUnsubscribe(t *testing.T) {
eb := NewEventBus()
jobAddedCh := make(chan interface{}, 1)
eb.Subscribe(JobAdded, jobAddedCh)
eb.Unsubscribe(JobAdded, jobAddedCh)
jobData := "New Job Data"
eb.Publish(JobAdded, jobData)
select {
case <-jobAddedCh:
t.Error("Received data after unsubscribing")
case <-time.After(1 * time.Second):
// Test passes if it times out (no data received)
}
}
func TestMultipleSubscribers(t *testing.T) {
eb := NewEventBus()
jobAddedCh1 := make(chan interface{}, 1)
jobAddedCh2 := make(chan interface{}, 1)
eb.Subscribe(JobAdded, jobAddedCh1)
eb.Subscribe(JobAdded, jobAddedCh2)
jobData := "New Job Data"
eb.Publish(JobAdded, jobData)
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
select {
case receivedData := <-jobAddedCh1:
rd := receivedData.(Event)
if rd.Data != jobData {
t.Errorf("Received data %v, want %v", receivedData, jobData)
}
case <-time.After(1 * time.Second):
t.Error("Timed out waiting for published event on channel 1")
}
}()
go func() {
defer wg.Done()
select {
case receivedData := <-jobAddedCh2:
rd := receivedData.(Event)
if rd.Data != jobData {
t.Errorf("Received data %v, want %v", receivedData, jobData)
}
case <-time.After(1 * time.Second):
t.Error("Timed out waiting for published event on channel 2")
}
}()
wg.Wait()
}
package jobqueue
import (
"context"
"sync"
"sync/atomic"
"time"
)
const (
MODE_STOPPED = iota
MODE_RUNNING
MODE_PAUSED
)
type mode int32
type shouldStopFunc func(executor *jobExecutor) bool
type jobExecutor struct {
mutex sync.Mutex
Queue JobsInterface
Ctx context.Context
CancelFunc context.CancelFunc
MaxParallel int
interval time.Duration
Ticker *time.Ticker
cleanupTimer *time.Ticker
//stopChan chan struct{}
sem chan struct{}
pauseChan chan struct{}
resumeChan chan struct{}
runningMode int32
doneChan chan struct{}
shouldStop shouldStopFunc
}
func NewJobExecutor(queue JobsInterface, maxParallel int, interval time.Duration, shouldStopFunc shouldStopFunc) *jobExecutor {
execCtx, cancelFunc := context.WithCancel(context.Background())
return &jobExecutor{
Queue: queue,
Ctx: execCtx,
CancelFunc: cancelFunc,
MaxParallel: maxParallel,
interval: interval,
Ticker: nil,
cleanupTimer: nil,
//stopChan: make(chan struct{}),
sem: make(chan struct{}, maxParallel),
pauseChan: make(chan struct{}),
resumeChan: make(chan struct{}),
runningMode: MODE_STOPPED,
shouldStop: shouldStopFunc,
}
}
func (je *jobExecutor) executeJobs() {
je.mutex.Lock()
je.Ticker = time.NewTicker(je.interval)
je.cleanupTimer = time.NewTicker(10 * je.interval)
je.setRunningFlag(MODE_RUNNING)
je.mutex.Unlock()
for {
select {
case <-je.Ticker.C:
if !je.IsPaused() {
je.runJobs()
if je.shouldStop != nil && je.shouldStop(je) {
_ = je.Stop()
return
}
}
case <-je.cleanupTimer.C:
je.Queue.Cleanup()
case <-je.pauseChan:
je.setRunningFlag(MODE_PAUSED)
case <-je.resumeChan:
je.setRunningFlag(MODE_RUNNING)
case <-je.Ctx.Done():
je.mutex.Lock()
je.Ticker.Stop()
je.cleanupTimer.Stop()
je.setRunningFlag(MODE_STOPPED)
je.mutex.Unlock()
return
}
}
}
func (je *jobExecutor) runJobs() {
// Get jobs that can be executed
jobs := je.Queue.GetExecutableJobs()
if len(jobs) == 0 {
return
}
var wg sync.WaitGroup
// Map to track the status of executed jobs
jobStatus := make(map[JobIDType]bool)
for _, job := range jobs {
jobStatus[job.GetId()] = false
}
// Channel for coordinating job execution
jobChan := make(chan ReadOnlyJob)
// Determine the number of jobs to be sent to the channel
for _, job := range jobs {
dependencies := job.GetDependencies()
canRun := true
for _, dependencyID := range dependencies {
// Check if dependencies have already been executed
if !jobStatus[dependencyID] {
canRun = false
break
}
}
if canRun {
wg.Add(1) // Increment the WaitGroup counter for each job to be sent
}
}
// Loop through all jobs and execute only if dependencies are met
go func() {
for _, job := range jobs {
dependencies := job.GetDependencies()
canRun := true
for _, dependencyID := range dependencies {
// Check if dependencies have already been executed
if !jobStatus[dependencyID] {
canRun = false
break
}
}
if canRun {
// Send the job to the job channel
jobChan <- job
}
}
close(jobChan) // Close the channel after all jobs have been sent
}()
maxParallel := je.MaxParallel
if len(jobs) < maxParallel {
maxParallel = len(jobs)
}
// Execute jobs in parallel
for i := 0; i < maxParallel; i++ {
go func() {
for job := range jobChan {
job.Run(je.Ctx)
// Mark the job as executed
jobStatus[job.GetId()] = true
wg.Done()
}
}()
}
// Wait for all jobs to complete before returning
wg.Wait()
}
func (je *jobExecutor) Start() error {
if je.IsRunning() {
return ErrAlreadyStarted
}
if je.IsPaused() {
return je.Resume()
}
go je.executeJobs()
return nil
}
func (je *jobExecutor) Stop() error {
if !je.IsRunning() && !je.IsPaused() {
return ErrAlreadyStopped
}
je.CancelFunc()
return nil
}
func (je *jobExecutor) Pause() error {
if je.IsPaused() {
return ErrAlreadyPaused
}
je.mutex.Lock()
je.pauseChan <- struct{}{}
je.setRunningFlag(MODE_PAUSED)
je.mutex.Unlock()
return nil
}
func (je *jobExecutor) Resume() error {
if !je.IsPaused() {
return ErrNotPaused
}
je.mutex.Lock()
je.resumeChan <- struct{}{}
je.setRunningFlag(MODE_RUNNING)
je.mutex.Unlock()
return nil
}
func (je *jobExecutor) IsPaused() bool {
return atomic.LoadInt32(&je.runningMode) == MODE_PAUSED
}
func (je *jobExecutor) IsRunning() bool {
return atomic.LoadInt32(&je.runningMode) == MODE_RUNNING
}
func (je *jobExecutor) setRunningFlag(mode int32) {
atomic.StoreInt32(&je.runningMode, mode)
}
package jobqueue
import (
"context"
"testing"
"time"
)
type TestRunnable struct{}
func (r TestRunnable) Run(ctx context.Context) (int, any, error) {
// Dummy run implementation
return 0, nil, nil
}
func TestJobExecutorStartAndStop(t *testing.T) {
queue := NewJobs()
executor := NewJobExecutor(queue, 1, time.Millisecond*50, nil)
// Fügen Sie einen Job zur Warteschlange hinzu
err := queue.AddJob(JobSpecification{
Id: "test-job",
Priority: 1,
Concurrency: 1,
}, TestRunnable{})
if err != nil {
t.Fatalf("Failed to add job: %v", err)
}
err = executor.Start()
if err != nil {
t.Errorf("Failed to start executor: %v", err)
}
for i := 0; i < 10; i++ {
time.Sleep(time.Millisecond * 100)
if executor.IsRunning() {
break
}
}
if !executor.IsRunning() {
t.Errorf("Executor should be running")
}
err = executor.Stop()
for i := 0; i < 10; i++ {
time.Sleep(time.Millisecond * 100)
if !executor.IsRunning() {
break
}
}
if err != nil {
t.Errorf("Failed to stop executor: %v", err)
}
if executor.IsRunning() {
t.Errorf("Executor should not be running")
}
}
func TestJobExecutorPauseAndResume(t *testing.T) {
queue := NewJobs()
executor := NewJobExecutor(queue, 1, time.Millisecond*50, nil)
// Fügen Sie einen Job zur Warteschlange hinzu
err := queue.AddJob(JobSpecification{
Id: "test-job",
Priority: 1,
Concurrency: 1,
}, TestRunnable{})
if err != nil {
t.Fatalf("Failed to add job: %v", err)
}
err = executor.Start()
if err != nil {
t.Errorf("Failed to start executor: %v", err)
}
for i := 0; i < 10; i++ {
time.Sleep(time.Millisecond * 100)
if executor.IsRunning() {
break
}
}
err = executor.Pause()
if err != nil {
t.Errorf("Failed to pause executor: %v", err)
}
for i := 0; i < 10; i++ {
time.Sleep(time.Millisecond * 100)
if executor.IsPaused() {
break
}
}
if !executor.IsPaused() {
t.Errorf("Executor should be paused")
}
err = executor.Resume()
if err != nil {
t.Errorf("Failed to resume executor: %v", err)
}
for i := 0; i < 10; i++ {
time.Sleep(time.Millisecond * 100)
if executor.IsRunning() {
break
}
}
if executor.IsPaused() {
t.Errorf("Executor should not be paused")
}
err = executor.Stop()
if err != nil {
t.Errorf("Failed to stop executor: %v", err)
}
for i := 0; i < 10; i++ {
time.Sleep(time.Millisecond * 100)
if !executor.IsRunning() {
break
}
}
if executor.IsRunning() {
t.Errorf("Executor should not be running")
}
}
...@@ -3,19 +3,47 @@ module gitlab.schukai.com/oss/libraries/go/services/job-queues.git ...@@ -3,19 +3,47 @@ module gitlab.schukai.com/oss/libraries/go/services/job-queues.git
go 1.20 go 1.20
require ( require (
github.com/docker/docker v24.0.6+incompatible
github.com/pkg/sftp v1.13.6
github.com/robfig/cron/v3 v3.0.1
github.com/shirou/gopsutil/v3 v3.23.9
github.com/stretchr/testify v1.8.4
golang.org/x/crypto v0.14.0
gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/mysql v1.5.2
gorm.io/gorm v1.25.5
)
require (
github.com/DATA-DOG/go-sqlmock v1.5.0 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect github.com/distribution/reference v0.5.0 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/lufia/plan9stats v0.0.0-20231016141302-07b5767bb0ed // indirect
github.com/moby/term v0.5.0 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
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-20210106213030-5aafc221ea8c // indirect github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/shirou/gopsutil/v3 v3.23.9 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/stretchr/testify v1.8.4 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect github.com/tklauser/numcpus v0.6.1 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect
golang.org/x/sys v0.12.0 // indirect golang.org/x/mod v0.8.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect golang.org/x/net v0.10.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.6.0 // indirect
gotest.tools/v3 v3.5.1 // indirect
) )
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v24.0.6+incompatible h1:hceabKCtUgDqPu+qm0NgsaXf28Ljf4/pWFL7xjWWDgE=
github.com/docker/docker v24.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/lufia/plan9stats v0.0.0-20231016141302-07b5767bb0ed h1:036IscGBfJsFIgJQzlui7nK1Ncm0tp2ktmPj8xO4N/0=
github.com/lufia/plan9stats v0.0.0-20231016141302-07b5767bb0ed/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo=
github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/robfig/cron/v3 v3.0.0 h1:kQ6Cb7aHOHTSzNVNEhmp8EcWKLb4CbiMW9h9VyIhO4E= github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b h1:0LFwY6Q3gMACTjAbMZBjXAqTOzOwFaj2Ld6cjeQ7Rig=
github.com/robfig/cron/v3 v3.0.0/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b/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.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil/v3 v3.23.9 h1:ZI5bWVeu2ep4/DIxB4U9okeYJ7zp/QLTO4auRb/ty/E= github.com/shirou/gopsutil/v3 v3.23.9 h1:ZI5bWVeu2ep4/DIxB4U9okeYJ7zp/QLTO4auRb/ty/E=
github.com/shirou/gopsutil/v3 v3.23.9/go.mod h1:x/NWSb71eMcjFIO0vhyGW5nZ7oSIgVjrCnADckb85GA= github.com/shirou/gopsutil/v3 v3.23.9/go.mod h1:x/NWSb71eMcjFIO0vhyGW5nZ7oSIgVjrCnADckb85GA=
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/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
...@@ -34,16 +75,82 @@ github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFA ...@@ -34,16 +75,82 @@ github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFA
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/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
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.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/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.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/mysql v1.5.2 h1:QC2HRskSE75wBuOxe0+iCkyJZ+RqpudsQtqkp+IMuXs=
gorm.io/driver/mysql v1.5.2/go.mod h1:pQLhh1Ut/WUAySdTHwBpBv6+JKcj+ua4ZFx1QQTBzb8=
gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls=
gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
package jobqueue
import (
"bytes"
"encoding/gob"
"sync"
)
// SerializeJob serializes JobData and JobSpecification into a byte slice
func (j *job) SerializeJob() ([]byte, error) {
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
if err := enc.Encode(j.JobData); err != nil {
return nil, err
}
if err := enc.Encode(j.JobSpecification); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
// DeserializeJob deserializes a byte slice into a job struct
func DeserializeJob(data []byte) (*job, error) {
var jobData JobData
var jobSpec JobSpecification
buf := bytes.NewBuffer(data)
dec := gob.NewDecoder(buf)
if err := dec.Decode(&jobData); err != nil {
return nil, err
}
if err := dec.Decode(&jobSpec); err != nil {
return nil, err
}
job := &job{
JobData: jobData,
JobSpecification: jobSpec,
mu: sync.Mutex{},
//ctx: context.Background(),
}
return job, nil
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment