docs: protected void poll() {
          int missCount = 0;
          String curQueue = null;
          while (RUNNING.equals(this.state.get())) {
              try {
                  if (threadNameChangingEnabled) {
                      renameThread("Waiting for " + JesqueUtils.join(",", this.queueNames));
                  }
                  curQueue = getNextQueue();
                  if (curQueue != null) {
                      checkPaused();
                      // Might have been waiting in poll()/checkPaused() for a while
                      if (RUNNING.equals(this.state.get())) {
                          this.listenerDelegate.fireEvent(WORKER_POLL, this, curQueue, null, null, null, null);
                          final String payload = pop(curQueue);
                          if (payload != null) {
                              process(ObjectMapperFactory.get().readValue(payload, Job.class), curQueue);
                              missCount = 0;
                          } else {
                              missCount++;
                              if (shouldSleep(missCount) && RUNNING.equals(this.state.get())) {
                                  // Keeps worker from busy-spinning on empty queues
                                  missCount = 0;
                                  Thread.sleep(EMPTY_QUEUE_SLEEP_TIME);
                              }
                          }
                      }
                  }
              } catch (InterruptedException ie) {
                  if (!isShutdown()) {
                      recoverFromException(curQueue, ie);
                  }
              } catch (JsonParseException | JsonMappingException e) {
                  // If the job JSON is not deserializable, we never want to submit it again...
                  removeInFlight(curQueue, true);
                  recoverFromException(curQueue, e);
              } catch (Exception e) {
                  recoverFromException(curQueue, e);
              }
          }
      }