Apps typically process requests until completion. However, users may cancel long-running tasks. Implementing graceful cancellation ensures resources are released immediately and partial results are handled correctly.
The Cancel Hook
Define a cancel method in your App class. This method is called when the supervisor receives a cancellation signal.
1class App(BaseApp):2 async def setup(self, config):3 self.cancel_flag = False45 async def on_cancel(self):6 """Called when user cancels the task"""7 print("Cancellation requested...")8 self.cancel_flag = True9 return True1011 async def run(self, input):12 self.cancel_flag = False13 for i in range(100):14 if self.cancel_flag:15 print("Stopping work...")16 break17 await self.heavy_computation(i)Node.js apps can also check this.context.cancelRequested, which is set automatically by the kernel.
Best Practices
-
Check Frequently: In loops, check your cancellation flag at the start of every iteration.
-
Clean Up: Close database connections, delete temporary files, or free GPU memory before exiting.
-
Return Quickly: The cancel handler should be fast. Do not block execution there; just set a flag or signal an event.
-
Force Kill: If an app does not respond to the cancel hook within the grace period (default 10 seconds), it will be forcefully terminated. Callers can also request immediate force-kill:
- REST API:
POST /tasks/:id/cancelwith{"force": true}— see Cancel task - CLI:
belt task cancel <task-id> --force
Use force kill only when graceful cancellation is stuck or too slow.
- REST API: