Key the package processing lease on project, name and version

Two pushes of the same new package version at the same moment can both pass the duplicate check. This happens with RubyGems and NuGet.

Why
  • The lease key is per temp package. lease_key uses package.id. When no version exists yet, each upload keys the lease on its own temporary package, so the two leases don't block each other.
  • NuGet has the same gap. Its lease_key falls back to @package_file.package_id when no package exists yet.
  • A taken lease isn't retried. Today the second worker skips processing and leaves the package in processing.

Found during review of !264067 (merged).

Proposal

  • Key the lease on project, package name and version for every async format.
  • Retry the job when the lease is taken, instead of skipping it.