Skip to content

Commit 8b9a057

Browse files
committed
[apiserver/edgefunction] Cleanup on GC
1 parent a09681b commit 8b9a057

File tree

3 files changed

+73
-6
lines changed

3 files changed

+73
-6
lines changed

pkg/apiserver/extensions/edgefunctionrevision.go

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"sort"
66
"time"
77

8+
tclient "go.temporal.io/sdk/client"
89
"k8s.io/apimachinery/pkg/api/errors"
910
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1011
"k8s.io/apimachinery/pkg/runtime"
@@ -14,6 +15,7 @@ import (
1415
"sigs.k8s.io/controller-runtime/pkg/reconcile"
1516

1617
extensionsv1alpha2 "github.com/apoxy-dev/apoxy-cli/api/extensions/v1alpha2"
18+
"github.com/apoxy-dev/apoxy-cli/pkg/apiserver/ingest"
1719
)
1820

1921
const (
@@ -25,21 +27,22 @@ var _ reconcile.Reconciler = &EdgeFunctionRevisionGCReconciler{}
2527
// EdgeFunctionRevisionGCReconciler garbage collects EdgeFunctionRevisions.
2628
type EdgeFunctionRevisionGCReconciler struct {
2729
client.Client
28-
Scheme *runtime.Scheme
29-
30+
scheme *runtime.Scheme
31+
tc tclient.Client
3032
gcInterval time.Duration
3133
}
3234

3335
// NewEdgeFunctionRevisionGCReconciler returns a new EdgeFunctionRevisionGCReconciler.
3436
func NewEdgeFunctionRevisionGCReconciler(
3537
c client.Client,
3638
s *runtime.Scheme,
39+
tc tclient.Client,
3740
gcInterval time.Duration,
3841
) *EdgeFunctionRevisionGCReconciler {
3942
return &EdgeFunctionRevisionGCReconciler{
40-
Client: c,
41-
Scheme: s,
42-
43+
Client: c,
44+
scheme: s,
45+
tc: tc,
4346
gcInterval: gcInterval,
4447
}
4548
}
@@ -81,6 +84,18 @@ func (r *EdgeFunctionRevisionGCReconciler) Reconcile(ctx context.Context, req re
8184
log.Error(err, "Failed to delete old revision", "revision", revision.Name)
8285
continue
8386
}
87+
// Execute cleanup workflow.
88+
wOpts := tclient.StartWorkflowOptions{
89+
ID: revision.Name + "-cleanup",
90+
TaskQueue: ingest.EdgeFunctionCleanupQueue,
91+
WorkflowExecutionTimeout: 10 * time.Minute,
92+
}
93+
in := &ingest.EdgeFunctionIngestParams{
94+
Obj: revision.DeepCopy(),
95+
}
96+
if _, err := r.tc.ExecuteWorkflow(ctx, wOpts, ingest.EdgeFunctionCleanupWorkflow, in); err != nil {
97+
log.Error(err, "Failed to start cleanup workflow", "revision", revision.Name)
98+
}
8499
log.Info("Deleted old revision", "revision", revision.Name)
85100
}
86101
}

pkg/apiserver/ingest/edgefunction.go

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ import (
4141
)
4242

4343
const (
44-
EdgeFunctionIngestQueue = "EDGE_FUNC_INGEST_TASK_QUEUE"
44+
EdgeFunctionIngestQueue = "EDGE_FUNC_INGEST_TASK_QUEUE"
45+
EdgeFunctionCleanupQueue = "EDGE_FUNC_CLEANUP_TASK_QUEUE"
4546
)
4647

4748
const (
@@ -61,6 +62,7 @@ type IngestResult struct {
6162
// RegisterWorkflows registers Edge Function workflows with the Temporal worker.
6263
func RegisterWorkflows(w tworker.Worker) {
6364
w.RegisterWorkflow(EdgeFunctionIngestWorkflow)
65+
w.RegisterWorkflow(EdgeFunctionCleanupWorkflow)
6466
}
6567

6668
// EdgeFunctionIngestWorkflow is a Temporal workflow that ingests Edge Functions.
@@ -191,6 +193,35 @@ Finalize:
191193
return nil
192194
}
193195

196+
func EdgeFunctionCleanupWorkflow(ctx workflow.Context, in *EdgeFunctionIngestParams) error {
197+
opts := workflow.ActivityOptions{
198+
StartToCloseTimeout: 10 * time.Minute,
199+
RetryPolicy: &temporal.RetryPolicy{
200+
InitialInterval: time.Second,
201+
BackoffCoefficient: 2.0,
202+
MaximumInterval: 10 * time.Second,
203+
MaximumAttempts: 3,
204+
},
205+
}
206+
ctx = workflow.WithActivityOptions(ctx, opts)
207+
log := tlog.With(workflow.GetLogger(ctx), "Name", in.Obj.Name, "ResourceVersion", in.Obj.ResourceVersion)
208+
209+
var w *worker
210+
211+
if err := workflow.ExecuteActivity(ctx, w.CleanupStagedData, in).Get(ctx, nil); err != nil {
212+
log.Error("Failed to cleanup staged data", "Error", err)
213+
return err
214+
}
215+
216+
if err := workflow.ExecuteActivity(ctx, w.CleanupStoredData, in).Get(ctx, nil); err != nil {
217+
log.Error("Failed to cleanup stored data", "Error", err)
218+
return err
219+
}
220+
221+
log.Info("Edge Function cleanup completed successfully")
222+
return nil
223+
}
224+
194225
// Worker implements Temporal Activities for Edge Functions Ingest queue.
195226
type worker struct {
196227
k8s kubernetes.Interface
@@ -223,6 +254,7 @@ func (w *worker) RegisterActivities(tw tworker.Worker) {
223254
tw.RegisterActivity(w.StoreGoPluginActivity)
224255
tw.RegisterActivity(w.FinalizeActivity)
225256
tw.RegisterActivity(w.CleanupStagedData)
257+
tw.RegisterActivity(w.CleanupStoredData)
226258
}
227259

228260
func (w *worker) AddIngestConditionActivity(
@@ -872,6 +904,25 @@ func (w *worker) CleanupStagedData(
872904
return nil
873905
}
874906

907+
func (w *worker) CleanupStoredData(
908+
ctx context.Context,
909+
in *EdgeFunctionIngestParams,
910+
) error {
911+
log := tlog.With(activity.GetLogger(ctx), "Name", in.Obj.Name, "ResourceVersion", in.Obj.ResourceVersion)
912+
log.Info("Cleaning up stored data")
913+
914+
wid := activity.GetInfo(ctx).WorkflowExecution.ID
915+
storeDir := w.storeDir(wid)
916+
917+
if err := os.RemoveAll(storeDir); err != nil {
918+
log.Error("Failed to remove store directory", "Error", err)
919+
return err
920+
}
921+
922+
log.Info("Store directory cleaned up successfully")
923+
return nil
924+
}
925+
875926
func hasCondition(conditions []metav1.Condition, condType string, status metav1.ConditionStatus) bool {
876927
for _, c := range conditions {
877928
if c.Type == condType && c.Status == status {

pkg/apiserver/manager.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ func (m *Manager) Start(
426426
if err := extensionscontroller.NewEdgeFunctionRevisionGCReconciler(
427427
m.manager.GetClient(),
428428
m.manager.GetScheme(),
429+
tc,
429430
dOpts.gcInterval,
430431
).SetupWithManager(ctx, m.manager); err != nil {
431432
return fmt.Errorf("failed to set up EdgeFunctionRevision GC controller: %v", err)

0 commit comments

Comments
 (0)