Run ITS actions asynchronously on a work queue

ITS event handling ran synchronously on Gerrit's event dispatch
thread. For every matching ref event, the plugin extracted
properties, evaluated rules, and executed the resulting actions
inline. Those actions perform blocking network calls to the issue
tracker (for example, the Jira REST API), which held up the
dispatch thread and could slow down the Gerrit operations that
produced the events.

Keep issue detection and rule evaluation on the dispatch thread, but
offload action execution to a dedicated thread pool backed by
Gerrit's WorkQueue. Work is queued only when an event actually
triggers an action, so events that match no rule add nothing to the
queue. Asynchronous execution is enabled when actions.threads is set
to a positive value in plugin config. The default of 0 preserves the
previous synchronous behavior.

Concurrent processing can reorder events and corrupt issue state
transitions (for example, in Jira). A per-change ordering key ensures
tasks for the same change run one at a time in submission order,
while unrelated changes run in parallel.

To keep the backlog bounded, the number of in-flight tasks is limited
to the pool size. When every thread is busy, submission blocks the
dispatch thread until a running task completes.

Change-Id: I9cf17b55fbf0fce836fcf8ed9f8909741e6a3911
10 files changed
tree: d0b3263f497796e30b79a099867c0dfe0a51348c
  1. .settings/
  2. src/
  3. tools/
  4. .bazelignore
  5. .bazelrc
  6. .gitignore
  7. bazlets.bzl
  8. BUILD
  9. LICENSE
  10. WORKSPACE