[
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