Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aether-users] SNAPSHOT artifacts: how to best access timestamped files

Andreas Sewe wrote:

Out of curiosity: Is this list of
properties documented somewhere (JavaDoc, Wiki, whatever)?

Depends on the property. Where I considered the property of general importance, it should be mentioned in the JavaDoc of the class employing it. For properties that I added mostly as some kind of safety net for certain behavior, there's no end user doc and I simply wait for users to present their use cases, thereby providing me with more insight into how things are used.

OK, if I understand you correctly, if all I know is a "-SNAPSHOT" GAV
and I want to find the place on disk where the current timestamps
artifact (if already downloaded) resides, neither
getPathForRemoteArtifact() nor find() will help me

Correct. getPathFor*() and find() are rather low-level operations that expect a GAV with concrete version.

- I noticed that you wrote resolveVersion() above rather than resolve().
Is resolveVersion() followed by getPathForRemoteArtifact(), I assume,
preferable to resolve(). If so, why? Intuitively, I would have just
called resolve() as a one-stop solution.

I merely mentioned resolveVersion() to complete the picture around usage of find(). Your intuition is right, resolve() is what you should use.

- Having a second session around (one in offline-mode, on online) raises
the question how synchronization among sessions needs to be handled.

As far as I understand Aether's design, a RepositorySystemSession is
basically just a parameter object grouping lots of settings, so having
more than one session around is in itself not a problem. How this fares
in the face of multi-threading, however, I am not so sure (and I haven't
found any examples using SyncContext, which presumably has something to
do with it).

Your understanding of the session object as a rather simple parameter bean is correct. It's basically the other half of all the *Request objects, meant to capture those parameters which usually remain the same across different requests.

There are various entities touched by a session with slightly different constraints:

In general, DefaultRepositorySystemSession itself is not thread-safe. But that shouldn't be an issue when properly used: The expectation is that a session gets set up once during some initialization phase and from there one, gets only read from. And mere reading by concurrent threads is no issue. So as long as configuring a session by thread A happens-before usage of the session by thread B, there's no danger to the session object itself.

The session holds a few mutable pieces like a cache and state. Those are backed by thread-safe implementations as required by API doc.

Any component referenced by the session which doesn't provide mutators is supposed to be thread-safe.

The only trouble with concurrency usually stems from the local repository and concurrent writes/reads to the filesystem. This is where the SyncContext comes generally into play but its current default impl is a noop. But similar to the session object itself, there's no harm with concurrency if only readers are involved.

- Given a "-SNAPSHOT" GAV, first check whether a timestamp artifact
exists in the local repo (presumably using resolution in offline mode).

- If it does not exist locally, schedule resolution of the "-SNAPSHOT"
GAV in online mode in another thread.

Now, I can guarantee that there is is only one online resolution job
running at any give time, but other threads might in the meantime
perform an offline-existance check using the local repo.

The online SNAPSHOT resolution eventually downloads newer metadata files to the local repo. With concurrent readers and writers, a reader could observe a partially written metadata file or observe an updated metadata file that points at a timestamped snapshots that is still being downloaded. So you need some form of synchronization to ensure proper operation here.

As mentioned above, the current SyncContext impl is an empty placeholder. You could swap in your own SyncContextFactory that does the required locking for a given artifact (if all you do is invoke resolveArtifact(), per-artifact synchronization should be sufficient, metadata resolution is a nested call and is guarded by the artifact-level lock). Depending on the required granularity of concurrency, it might be easier for you to employ say a ReadWriteLock in your threads and synchronize at that coarse level.

Hope that lengthy answer gets you further.


Benjamin


Back to the top