Skip to content

Commander

Commander is used for automatic management and execution of tasks. Each commander has an asynchronous queue and is managed by a commander loop. For thread safety, there is only one commander loop under each commander. If you need to add tasks outside of the thread, use thread-safe methods like put_job_threadsafe or call_handler_threadsafe. You can also use these methods to coordinate among multiple commanders, but this is usually unnecessary.

When instantiating a commander, you can set your logger through the logger parameter.

Run a commander

On launching a commander, you can set the initial Job, which can be a single Job or a sequence of Jobs (list, tuple, etc.). The commander will immediately start executing these Jobs after running. The CommanderAsync.run method can have a return value. By default, it returns None when the commander ends. However, it will return the value specified by return_result when using the CommanderAsync.exit method or the exit_commander method of Job and handler.

Note

Once a commander is launched, it immediately runs in a commander loop. This means that CommanderAsync.run will block the current thread until the commander exits.

Attempting to launch a commander that is already running will raise a CommanderAlreadyRunningError, and submitting tasks to a commander that has not started will raise a CommanderNotRunError. You can also use run_auto to start a commander and add tasks. It will automatically start the commander and run tasks if the commander is not running. If the commander is already running, it will add the tasks to the running commander.

Both run and run_auto can take an auto_exit parameter. If set to True, it will automatically end the commander after all tasks (including jobs and handlers) are completed.

Using the run_auto method to start a commander can automatically determine the running state of the commander and is safer, but it has the disadvantage of unpredictability in terms of whether the current thread will be blocked. If the commander is not running, it will start the commander and block the current thread. If the commander is already running, it will add the task to the current commander and return immediately. This means that you might not be able to clearly determine where the commander loop is running or which thread is being blocked by the commander loop. Therefore, it's generally recommended to use run for manual management of the commander loop. You can start the commander at the beginning of the program and manually close it at the end.

You can use the running_status property to check whether the commander is running (or has started). The is_empty method returns whether the commander is empty; it returns True when there are no running or pending jobs and handlers in the commander, otherwise False.

Exit commander

To manually end the commander, you can use the exit method. It takes two parameters: return_result and wait. Through the return_result parameter, you can specify the return value for the run method. When wait is set to True, the method will wait until the commander truly ends, otherwise, it returns immediately.

You can use wait_for_exit to wait for the commander to end. It doesn’t actively end the commander but passively waits until the commander ends before returning.

To add tasks from outside the commander loop (in a new thread), you can use put_job_threadsafe or call_handler_threadsafe. Generally, you are always submitting new Jobs or initiating new handlers inside a Job or handler, which is always thread-safe, and you can use methods provided by the Job or handler itself, referring to Job and handler.