Scheduling CreateNamespace
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
package infrastructure
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"oc-scheduler/conf"
|
||||
"oc-scheduler/infrastructure/scheduling"
|
||||
"time"
|
||||
|
||||
@@ -119,7 +121,8 @@ func (ws *WorkflowSchedule) UpsertSessionDrafts(wfID, executionsID string, selfI
|
||||
ex, _, err := utils.GenericStoreOne(exec, workflow_execution.NewAccessor(adminReq))
|
||||
if err == nil {
|
||||
RegisterExecLock(ex.GetID())
|
||||
go WatchExecDeadline(ex.GetID(), exec.ExecDate, selfID, request)
|
||||
go WatchExecDeadline(
|
||||
ex.GetID(), executionsID, exec.ExecDate, selfID, request)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,24 +272,71 @@ func emitNATSRemove(id, schedulerPeerID, executionsID string, dt tools.DataType)
|
||||
// Deadline watchers
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// WatchExecDeadline purges all unconfirmed bookings/purchases for an execution
|
||||
// one minute before its scheduled start, to avoid stale drafts blocking resources.
|
||||
// WatchExecDeadline fires one minute before the execution start date.
|
||||
// If the execution is still a draft it is purged; otherwise the namespace
|
||||
// is created and a WatchExecEnd watcher is armed.
|
||||
// If the deadline has already passed (e.g. after a process restart), it fires immediately.
|
||||
func WatchExecDeadline(executionID string, execDate time.Time, selfID *peer.Peer, request *tools.APIRequest) {
|
||||
func WatchExecDeadline(executionID string, ns string, execDate time.Time, selfID *peer.Peer, request *tools.APIRequest) {
|
||||
fmt.Println("WatchExecDeadline")
|
||||
delay := time.Until(execDate.UTC().Add(-1 * time.Minute))
|
||||
if delay <= 0 {
|
||||
go purgeUnconfirmedExecution(executionID, selfID, request)
|
||||
go handleExecDeadline(executionID, ns, selfID, request)
|
||||
return
|
||||
}
|
||||
time.AfterFunc(delay, func() { purgeUnconfirmedExecution(executionID, selfID, request) })
|
||||
time.AfterFunc(delay, func() { handleExecDeadline(executionID, ns, selfID, request) })
|
||||
}
|
||||
|
||||
func purgeUnconfirmedExecution(executionID string, selfID *peer.Peer, request *tools.APIRequest) {
|
||||
acc := workflow_execution.NewAccessor(&tools.APIRequest{Admin: true})
|
||||
UnscheduleExecution(executionID, selfID, request)
|
||||
_, _, err := acc.DeleteOne(executionID)
|
||||
fmt.Printf("purgeUnconfirmedExecution: cleaned up resources for execution %s\n", err)
|
||||
func handleExecDeadline(executionID string, ns string, selfID *peer.Peer, request *tools.APIRequest) {
|
||||
adminReq := &tools.APIRequest{Admin: true}
|
||||
res, _, err := workflow_execution.NewAccessor(adminReq).LoadOne(executionID)
|
||||
if err != nil || res == nil {
|
||||
fmt.Printf("handleExecDeadline: execution %s not found\n", executionID)
|
||||
return
|
||||
}
|
||||
exec := res.(*workflow_execution.WorkflowExecution)
|
||||
if exec.IsDraft {
|
||||
UnscheduleExecution(executionID, selfID, request)
|
||||
workflow_execution.NewAccessor(adminReq).DeleteOne(executionID)
|
||||
fmt.Printf("handleExecDeadline: purged draft execution %s\n", executionID)
|
||||
return
|
||||
}
|
||||
if serv, err := tools.NewKubernetesService(
|
||||
conf.GetConfig().KubeHost+":"+conf.GetConfig().KubePort,
|
||||
conf.GetConfig().KubeCA, conf.GetConfig().KubeCert, conf.GetConfig().KubeData); err != nil {
|
||||
fmt.Printf("handleExecDeadline: k8s init failed for %s: %v\n", executionID, err)
|
||||
} else if err := serv.ProvisionExecutionNamespace(context.Background(), ns); err != nil {
|
||||
fmt.Printf("handleExecDeadline: failed to provision namespace for %s: %v\n", ns, err)
|
||||
}
|
||||
go WatchExecEnd(executionID, ns, exec.EndDate, exec.ExecDate)
|
||||
}
|
||||
|
||||
// WatchExecEnd fires at the execution end date (ExecDate+1h when EndDate is nil)
|
||||
// and deletes the Kubernetes namespace associated with the execution.
|
||||
func WatchExecEnd(executionID string, ns string, endDate *time.Time, execDate time.Time) {
|
||||
var end time.Time
|
||||
if endDate != nil {
|
||||
end = *endDate
|
||||
} else {
|
||||
end = execDate.UTC().Add(time.Hour)
|
||||
}
|
||||
delay := time.Until(end.UTC())
|
||||
fire := func() {
|
||||
serv, err := tools.NewKubernetesService(
|
||||
conf.GetConfig().KubeHost+":"+conf.GetConfig().KubePort,
|
||||
conf.GetConfig().KubeCA, conf.GetConfig().KubeCert, conf.GetConfig().KubeData)
|
||||
if err != nil {
|
||||
fmt.Printf("WatchExecEnd: k8s init failed for %s: %v\n", executionID, err)
|
||||
return
|
||||
}
|
||||
if err := serv.TeardownExecutionNamespace(context.Background(), ns); err != nil {
|
||||
fmt.Printf("WatchExecEnd: failed to teardown namespace %s: %v\n", ns, err)
|
||||
}
|
||||
}
|
||||
if delay <= 0 {
|
||||
go fire()
|
||||
return
|
||||
}
|
||||
time.AfterFunc(delay, fire)
|
||||
}
|
||||
|
||||
// RecoverDraftExecutions is called at startup to restore deadline watchers for
|
||||
@@ -308,7 +358,7 @@ func RecoverDraftExecutions() {
|
||||
continue
|
||||
}
|
||||
RegisterExecLock(exec.GetID())
|
||||
go WatchExecDeadline(exec.GetID(), exec.ExecDate, selfID, adminReq)
|
||||
go WatchExecDeadline(exec.GetID(), exec.ExecutionsID, exec.ExecDate, selfID, adminReq)
|
||||
}
|
||||
fmt.Printf("RecoverDraftExecutions: recovered %d draft executions\n", len(results))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user