@@ -92,20 +92,25 @@ func NewManagerWithLumeraClient(ctx context.Context, config config.Config, logge
9292
9393// CreateCascadeTask creates and starts a Cascade task using the new pattern
9494func (m * ManagerImpl ) CreateCascadeTask (ctx context.Context , filePath string , actionID , signature string ) (string , error ) {
95+ // Create a detached context immediately to prevent HTTP request cancellation
96+ taskCtx , cancel := context .WithCancel (context .Background ())
97+
9598 // First validate the action before creating the task
96- action , err := m .validateAction (ctx , actionID )
99+ action , err := m .validateAction (taskCtx , actionID )
97100 if err != nil {
101+ cancel () // Clean up if validation fails
98102 return "" , err
99103 }
100104
101105 // verify signature
102- if err := m .validateSignature (ctx , action , signature ); err != nil {
106+ if err := m .validateSignature (taskCtx , action , signature ); err != nil {
107+ cancel () // Clean up if signature validation fails
103108 return "" , err
104109 }
105110
106111 taskID := uuid .New ().String ()[:8 ]
107112
108- m .logger .Debug (ctx , "Generated task ID" , "taskID" , taskID )
113+ m .logger .Debug (taskCtx , "Generated task ID" , "taskID" , taskID )
109114
110115 baseTask := BaseTask {
111116 TaskID : taskID ,
@@ -122,23 +127,23 @@ func (m *ManagerImpl) CreateCascadeTask(ctx context.Context, filePath string, ac
122127 // Create cascade-specific task
123128 task := NewCascadeTask (baseTask , filePath , actionID )
124129
125- // Store task in cache
126- m .taskCache .Set (ctx , taskID , task , TaskTypeCascade , actionID )
130+ // Store task in cache with cancel function
131+ m .taskCache .Set (taskCtx , taskID , task , TaskTypeCascade , actionID , cancel )
127132
128133 // Ensure task is stored before returning
129134 m .taskCache .Wait ()
130135
131136 go func () {
132- m .logger .Debug (ctx , "Starting cascade task asynchronously" , "taskID" , taskID )
133- err := task .Run (ctx )
137+ m .logger .Debug (taskCtx , "Starting cascade task asynchronously" , "taskID" , taskID )
138+ err := task .Run (taskCtx )
134139 if err != nil {
135140 // Error handling is done via events in the task.Run method
136141 // This is just a failsafe in case something goes wrong
137- m .logger .Error (ctx , "Cascade task failed with error" , "taskID" , taskID , "error" , err )
142+ m .logger .Error (taskCtx , "Cascade task failed with error" , "taskID" , taskID , "error" , err )
138143 }
139144 }()
140145
141- m .logger .Info (ctx , "Cascade task created successfully" , "taskID" , taskID )
146+ m .logger .Info (taskCtx , "Cascade task created successfully" , "taskID" , taskID )
142147 return taskID , nil
143148}
144149
@@ -152,13 +157,19 @@ func (m *ManagerImpl) GetTask(ctx context.Context, taskID string) (*TaskEntry, b
152157func (m * ManagerImpl ) DeleteTask (ctx context.Context , taskID string ) error {
153158 m .logger .Info (ctx , "Deleting task" , "taskID" , taskID )
154159
155- // First check if the task exists
156- _ , exists := m .taskCache .Get (ctx , taskID )
160+ // First check if the task exists and get its entry
161+ taskEntry , exists := m .taskCache .Get (ctx , taskID )
157162 if ! exists {
158163 m .logger .Warn (ctx , "Task not found for deletion" , "taskID" , taskID )
159164 return fmt .Errorf ("task not found: %s" , taskID )
160165 }
161166
167+ // Cancel the task if it has a cancel function
168+ if taskEntry .Cancel != nil {
169+ m .logger .Info (ctx , "Cancelling task before deletion" , "taskID" , taskID )
170+ taskEntry .Cancel ()
171+ }
172+
162173 // Delete the task from the cache
163174 m .taskCache .Del (ctx , taskID )
164175
@@ -242,19 +253,25 @@ func (m *ManagerImpl) Close(ctx context.Context) {
242253}
243254
244255func (m * ManagerImpl ) CreateDownloadTask (ctx context.Context , actionID string , outputDir string , signature string ) (string , error ) {
256+ // Create a detached context immediately to prevent HTTP request cancellation
257+ taskCtx , cancel := context .WithCancel (context .Background ())
258+
245259 // First validate the action before creating the task
246- action , err := m .validateDownloadAction (ctx , actionID )
260+ action , err := m .validateDownloadAction (taskCtx , actionID )
247261 if err != nil {
262+ cancel () // Clean up if validation fails
248263 return "" , err
249264 }
250265 // Decode metadata to get the filename
251- metadata , err := m .lumeraClient .DecodeCascadeMetadata (ctx , action )
266+ metadata , err := m .lumeraClient .DecodeCascadeMetadata (taskCtx , action )
252267 if err != nil {
268+ cancel () // Clean up if metadata decode fails
253269 return "" , fmt .Errorf ("failed to decode cascade metadata: %w" , err )
254270 }
255271
256272 // Ensure we have a filename from metadata
257273 if metadata .FileName == "" {
274+ cancel () // Clean up if no filename
258275 return "" , fmt .Errorf ("no filename found in cascade metadata" )
259276 }
260277
@@ -263,7 +280,7 @@ func (m *ManagerImpl) CreateDownloadTask(ctx context.Context, actionID string, o
263280
264281 taskID := uuid .New ().String ()[:8 ]
265282
266- m .logger .Debug (ctx , "Generated download task ID" , "task_id" , taskID , "final_output_path" , finalOutputPath )
283+ m .logger .Debug (taskCtx , "Generated download task ID" , "task_id" , taskID , "final_output_path" , finalOutputPath )
267284
268285 baseTask := BaseTask {
269286 TaskID : taskID ,
@@ -280,22 +297,22 @@ func (m *ManagerImpl) CreateDownloadTask(ctx context.Context, actionID string, o
280297 // Use the final output path with the correct filename
281298 task := NewCascadeDownloadTask (baseTask , actionID , finalOutputPath , signature )
282299
283- // Store task in cache
284- m .taskCache .Set (ctx , taskID , task , TaskTypeCascade , actionID )
300+ // Store task in cache with cancel function
301+ m .taskCache .Set (taskCtx , taskID , task , TaskTypeCascade , actionID , cancel )
285302
286303 // Ensure task is stored before returning
287304 m .taskCache .Wait ()
288305
289306 go func () {
290- m .logger .Debug (ctx , "Starting download cascade task asynchronously" , "taskID" , taskID )
291- err := task .Run (ctx )
307+ m .logger .Debug (taskCtx , "Starting download cascade task asynchronously" , "taskID" , taskID )
308+ err := task .Run (taskCtx )
292309 if err != nil {
293310 // Error handling is done via events in the task.Run method
294311 // This is just a failsafe in case something goes wrong
295- m .logger .Error (ctx , "Download Cascade task failed with error" , "taskID" , taskID , "error" , err )
312+ m .logger .Error (taskCtx , "Download Cascade task failed with error" , "taskID" , taskID , "error" , err )
296313 }
297314 }()
298315
299- m .logger .Info (ctx , "Download Cascade task created successfully" , "taskID" , taskID , "outputPath" , finalOutputPath )
316+ m .logger .Info (taskCtx , "Download Cascade task created successfully" , "taskID" , taskID , "outputPath" , finalOutputPath )
300317 return taskID , nil
301318}
0 commit comments