def push(*metajobs)
      Que.internal_log(:job_buffer_push, self) do
        {
          maximum_size:  maximum_size,
          ids:           metajobs.map(&:id),
          current_queue: to_a,
        }
      end

      sync do
        return metajobs if _stopping?

        @array.concat(metajobs).sort!

        # Relying on the hash's contents being sorted, here.
        priority_queues.reverse_each do |_, pq|
          pq.waiting_count.times do
            job = _shift_job(pq.priority)
            break if job.nil? # False would mean we're stopping.
            pq.push(job)
          end
        end

        # If we passed the maximum buffer size, drop the lowest sort keys and
        # return their ids to be unlocked.
        overage = -_buffer_space
        pop(overage) if overage > 0
      end
    end
def push(*metajobs)
      Que.internal_log(:job_buffer_push, self) do
        {
          maximum_size:  maximum_size,
          ids:           metajobs.map(&:id),
          current_queue: to_a,
        }
      end

      sync do
        return metajobs if _stopping?

        @array.concat(metajobs).sort!

        # Relying on the hash's contents being sorted, here.
        priority_queues.reverse_each do |_, pq|
          pq.waiting_count.times do
            job = _shift_job(pq.priority)
            break if job.nil? # False would mean we're stopping.
            pq.push(job)
          end
        end

        # If we passed the maximum buffer size, drop the lowest sort keys and
        # return their ids to be unlocked.
        overage = -_buffer_space
        pop(overage) if overage > 0
      end
    end
Since we use a mutex, which is not reentrant, we have to be a little
 careful to not call a method that locks the mutex when we've already
 locked it. So, as a general rule, public methods handle locking the mutex
 when necessary, while private methods handle the actual underlying data
 changes. This lets us reuse those private methods without running into
 locking issues.