Class MasterProcedureScheduler

All Implemented Interfaces:

ProcedureScheduler for the Master Procedures. This ProcedureScheduler tries to provide to the ProcedureExecutor procedures that can be executed without having to wait on a lock. Most of the master operations can be executed concurrently, if they are operating on different tables (e.g. two create table procedures can be performed at the same time) or against two different servers; say two servers that crashed at about the same time.

Each procedure should implement an Interface providing information for this queue. For example table related procedures should implement TableProcedureInterface. Each procedure will be pushed in its own queue, and based on the operation type we may make smarter decisions: e.g. we can abort all the operations preceding a delete table, or similar.

Concurrency control

Concurrent access to member variables (tableRunQueue, serverRunQueue, locking, tableMap, serverBuckets) is controlled by schedLock(). This mainly includes:
  • AbstractProcedureScheduler.push(Procedure, boolean, boolean): A push will add a Queue back to run-queue when:
    1. Queue was empty before push (so must have been out of run-queue)
    2. Child procedure is added (which means parent procedure holds exclusive lock, and it must have moved Queue out of run-queue)
  • AbstractProcedureScheduler.poll(long): A poll will remove a Queue from run-queue when:
    1. Queue becomes empty after poll
    2. Exclusive lock is requested by polled procedure and lock is available (returns the procedure)
    3. Exclusive lock is requested but lock is not available (returns null)
    4. Polled procedure is child of parent holding exclusive lock and the next procedure is not a child
  • Namespace/table/region locks: Queue is added back to run-queue when lock being released is:
    1. Exclusive lock
    2. Last shared lock (in case queue was removed because next procedure in queue required exclusive lock)