Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorRequest.java18
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorSelector.java10
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java21
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/provisional/p2/artifact/repository/IArtifactRepository.java7
4 files changed, 50 insertions, 6 deletions
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorRequest.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorRequest.java
index 021f843be..3cca98864 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorRequest.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorRequest.java
@@ -130,7 +130,25 @@ public class MirrorRequest extends ArtifactRequest {
return destinationDescriptor;
}
+ /**
+ * Keep retrying the source repository until it reports back that it will be impossible
+ * to get the artifact from it.
+ * @param destinationDescriptor
+ * @param sourceDescriptor
+ * @param monitor
+ * @return the status of the transfer operation
+ */
private IStatus transfer(IArtifactDescriptor destinationDescriptor, IArtifactDescriptor sourceDescriptor, IProgressMonitor monitor) {
+ IStatus status = Status.OK_STATUS;
+ // go until we get one (OK), there are no more mirrors to consider or the operation is cancelled.
+ // TODO this needs to be redone with a much better mirror management scheme.
+ do {
+ status = transferSingle(destinationDescriptor, sourceDescriptor, monitor);
+ } while (status.getSeverity() == IStatus.ERROR && status.getCode() == IArtifactRepository.CODE_RETRY);
+ return status;
+ }
+
+ private IStatus transferSingle(IArtifactDescriptor destinationDescriptor, IArtifactDescriptor sourceDescriptor, IProgressMonitor monitor) {
OutputStream destination;
try {
destination = target.getOutputStream(destinationDescriptor);
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorSelector.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorSelector.java
index a155d709f..d72daab92 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorSelector.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorSelector.java
@@ -232,6 +232,16 @@ public class MirrorSelector {
}
}
+ /**
+ * Return whether or not all the mirrors for this selector have proven to be invalid
+ * @return whether or not there is a vaild mirror in this selector.
+ */
+ public synchronized boolean hasValidMirror() {
+ // return true if there is a mirror and it has not failed. Since the mirrors
+ // list is sorted with failures last, we only have to test the first element for failure.
+ return mirrors != null && mirrors.length > 0 && mirrors[0].failureCount == 0;
+ }
+
/**
* Selects a mirror from the given list of mirrors. Returns null if a mirror
* could not be found.
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java
index f7f0c1e69..215c3b09f 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java
@@ -421,14 +421,17 @@ public class SimpleArtifactRepository extends AbstractArtifactRepository impleme
IStatus result = getTransport().download(mirrorLocation, destination, monitor);
if (mirrors != null)
mirrors.reportResult(mirrorLocation, result);
- if (result.getSeverity() == IStatus.CANCEL)
+ if (result.isOK() || result.getSeverity() == IStatus.CANCEL)
return result;
if (monitor.isCanceled())
return Status.CANCEL_STATUS;
- if (result.isOK() || baseLocation.equals(mirrorLocation))
- return result;
- //maybe we hit a bad mirror - try the base location
- return getTransport().download(baseLocation, destination, monitor);
+ // If there are more valid mirrors then return an error with a special code that tells the caller
+ // to keep trying. Note that the message in the status is largely irrelevant but the child
+ // status tells the story of why we failed on this try.
+ // TODO find a better way of doing this.
+ if (mirrors != null && mirrors.hasValidMirror())
+ return new MultiStatus(Activator.ID, CODE_RETRY, new IStatus[] {result}, "Retry another mirror", null); //$NON-NLS-1$
+ return result;
}
/**
@@ -466,7 +469,13 @@ public class SimpleArtifactRepository extends AbstractArtifactRepository impleme
return status;
status = downloadArtifact(descriptor, destination, monitor);
- return reportStatus(descriptor, destination, status);
+ IStatus result = reportStatus(descriptor, destination, status);
+ // if the original status was RETRY then ensure that we return that status. It is
+ // however important to call reportStatus() either way as it updates information
+ // in addition to collecting status.
+ // TODO we should remove this when there is more time for testing.
+ return status.getCode() == CODE_RETRY ? status : result;
+
}
public synchronized IArtifactDescriptor[] getArtifactDescriptors(IArtifactKey key) {
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/provisional/p2/artifact/repository/IArtifactRepository.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/provisional/p2/artifact/repository/IArtifactRepository.java
index cbcec403e..2da166ee2 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/provisional/p2/artifact/repository/IArtifactRepository.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/provisional/p2/artifact/repository/IArtifactRepository.java
@@ -27,6 +27,13 @@ import org.eclipse.equinox.internal.provisional.spi.p2.artifact.repository.Abstr
* </p>
*/
public interface IArtifactRepository extends IRepository {
+
+ /**
+ * The return code to use when a client could/should retry a failed getArtifact() operation.
+ * For example, the repository may have additional mirrors that could be consulted.
+ */
+ public static int CODE_RETRY = 13;
+
/**
* Add the given descriptor to the set of descriptors in this repository. This is
* a relatively low-level operation that should be used only when the actual related

Back to the top