* docs: Change comment position
* refactor(procedure): Store error in ProcedureState
* test: Mock instance with procedure enabled
* feat: Add wait method to wait for procedure
* test(datanode): Test create table by procedure
* chore: Fix clippy
* refactor: Use watch channel to store ProcedureState
* feat: Add a watcher to wait for state change
* test: test watcher on procedure failure
* feat: Only clear message cache on success
* feat: submit returns Watcher
* feat: wip
* feat: Implement procedure to create mito table
* feat: Add create_table_procedure to TableEngine
* feat: Impl dump and lock for CreateMitoTable
* feat: Impl CreateMitoTable::execute and register it to manager
* feat(common-procedure): pub local mod
* feat: Add simple test for MitoCreateTable
* style: Fix clippy
* refactor: Move create_table_procedure to a new trait TableEngineProcedure
* feat: Add ContextProvider to Context
So procedures can query states of other procedures via the
ContextProvider and they don't need to hold a ProcedureManagerRef
* feat: Procedure supports acquring multiple lock keys
* test: Use multi-locks in test
* feat: Add keys_to_lock/unlock
* feat: Runner executes procedure
* feat: Add rollback key type to ParsedKey
* feat: Write rollback key when procedure is unable to execute
* feat: Use loaded step to re-submit subprocedure
* feat: Track subprocedures in ProcedureMeta
* feat: Clean message cache after the root procedure is done
* feat: Runner returns execution result
* fix: Fix tests
* test: Test Runner
* test: Test procedures_in_tree
* chore: Refine test and comments
* feat: Remove support of lock inheritance
A deadlock happens if a subprocedure acquires the same lock key as
its parent.
The main concern is if the subprocedure directly inherits its parent's
lock, then how should we behave when multiple subprocedures acquire
this same lock? Each procedure may assume it has unique access to the
same object but it actually shares the resource with others.
Now subprocedures need to use different keys to lock objects, which is
reasonable. For example:
- A parent procedure wants to create a table so it locks the table with
a key like `catalog.schema.table`
- Subprocedures create regions for the table so they lock the regions
with keys `catalog.schema.table.region-0 ~ catalog.schema.table.region-n`
* style: Fix clippy
* feat: insert_procedure returns false on duplicate procedure
Also rename this method to try_insert_procedure
* chore: Address CR comments