About SyncContextFactory

This module among others, implements SyncContextFactory. The SyncContextFactory component is responsible to synchronize (coordinate) access to shared resources in Maven Resolver internals. Some examples:

  • single threaded (ST) build on a single host: given resolution by default happens in multi threaded (MT) way, files in a local repository must be protected from simultaneous access. In this case, it is enough for coordination to happen “locally”, at single JVM process level.
  • multi threaded (MT) build on a single host: same issues as above, but multiplied by MT build threads. As above, in this case, it is enough for coordination to happen “locally”, at JVM process level.
  • multi process (MP) build on a single host: in case multiple processes “share” (access, are set to use) the same local repository, coordination must exist between processes as well. Here the coordination must span across multiple JVM processes sharing same resource.
  • multi process (MP) build on multiple hosts using same (for example NFS mounted) local repository. Here again, the shared resource (the NFS mounted local repository) should be protected from simultaneous access. Here the coordination must span all the processes across all the hosts involved.

As can be seen, the ST and MT cases can be solved by “local” locking at JVM level only. In MP single host case a cross process, and in MP multi-host case a cross process and cross host coordination is required.

The defaults in Maven Resolver cover ST and MT cases out of the box (by default).

This module implementation for the interface org.eclipse.aether.spi.synccontext.SyncContextFactory uses resolver named locks.

Configuration Options for “named” SyncContextFactory

You can control and configure several aspects of NamedSyncContextFactory:

  • aether.syncContext.named.factory (optional, default is rwlock-local): the named lock factory to be used.
  • aether.syncContext.named.nameMapper (optional, default is gav): creates lock names out of artifact coordinates.
  • aether.syncContext.named.time (optional, default is 30): the time value for being blocked by trying to acquire a lock.
  • aether.syncContext.named.time.unit (optional, default is java.util.concurrent.TimeUnit.SECONDS): the time unit of time value.

For the aether.syncContext.named.factory property following values are allowed:

  • rwlock-local (default), uses JVM ReentrantReadWriteLock per lock name, usable for MT builds.
  • semaphore-local, uses JVM Semaphore per lock name, usable for MT builds.
  • file-lock, uses advisory file locking, usable for MP builds (must be used with any of file- prefixed name mapping).
  • noop, implement no-op locking (no locking). For experimenting only. Has same functionality as old “nolock” SyncContextFactory implementation.

For the aether.syncContext.named.nameMapper property following values are allowed:

  • discriminating (default), uses hostname + local repo + GAV to create unique lock names for artifacts.
  • gav uses GAV to create unique lock names for artifacts and metadata. Is not unique if multiple local repositories are involved.
  • file-gav uses GAV and session to create absolute file paths (to be used with file-lock factory)
  • file-hgav uses more compact layout than file-gav by SHA-1 digest, similar to git (to be used with file-lock factory)
  • static uses static (same) string as lock name for any input. Effectively providing functionality same as old “global” locking SyncContextFactory. Mostly for testing/experimental purposes.
  • file-static same as static but to be used with file-lock factory. Mostly for testing/experimental purposes.

Extra values for factory (these need extra setup and will work with Sisu DI only):

  • semaphore-hazelcast, distributed, usable with MT and MP builds, extra setup needed.
  • semaphore-hazelcast-client, distributed, usable with MT and MP builds, extra setup needed.
  • rwlock-redisson, distributed, usable with MT and MP builds, extra setup needed.
  • semaphore-redisson, distributed, usable with MT and MP builds, extra setup needed.

Other configuration keys:

  • aether.syncContext.named.basedir.locksDir, the relative or absolute directory path to to store the lock files. If relative, is resolved against local repository, if absolute, is used as is. If not set, defaults to “.locks”.
  • aether.syncContext.named.discriminating.discriminator, when discriminating name mapper is used, sets the a discriminator uniquely identifying a host and local repository pair. If not set, discriminator is calculated by applying sha1(hostname + ":" + localRepoPath) + GAV name mapper.
  • aether.syncContext.named.discriminating.hostname, the hostname to be used to calculate discriminator value, if above value not set. If not set, the hostname is detected using Java API.
  • aether.syncContext.named.hashing.depth, the depth of sub-directories (0=xxxx…, 1=xx/xxxx…, 2=xx/xx/xxxx…, etc) to be created by HashingNameMapper (used with file-hgav mapper). Only integer values from 0 to 4 are accepted (inclusive). If not set, defaults to 2.