Ticket #23738: 23738-4.patch

File 23738-4.patch, 8.3 KB (added by GerdP, 22 months ago)

Improve handling of upload into open changeset

  • src/org/openstreetmap/josm/gui/io/UploadPrimitivesTask.java

     
    8484
    8585    /**
    8686     * Prompt the user about how to proceed.
     87     * @param source the source of the changeset exception
    8788     *
    8889     * @return the policy selected by the user
    8990     */
    90     protected MaxChangesetSizeExceededPolicy promptUserForPolicy() {
     91    protected MaxChangesetSizeExceededPolicy promptUserForPolicy(ChangesetClosedException.Source source) {
    9192        ButtonSpec[] specs = {
    9293                new ButtonSpec(
    9394                        tr("Continue uploading"),
     
    109110                )
    110111        };
    111112        int numObjectsToUploadLeft = toUpload.getSize() - processedPrimitives.size();
    112         String msg1 = tr("The server reported that the current changeset was closed.<br>"
    113                 + "This is most likely because the changesets size exceeded the max. size<br>"
    114                 + "of {0} objects on the server ''{1}''.",
    115                 OsmApi.getOsmApi().getCapabilities().getMaxChangesetSize(),
    116                 OsmApi.getOsmApi().getBaseUrl()
    117         );
     113        final String msg1;
     114        if (source == ChangesetClosedException.Source.PREPARE_FURTHER_UPLOAD) {
     115            msg1 = tr("The current changeset is full.<br>"
     116                    + "This is because the changesets size reached the max. size<br>"
     117                    + "of {0} objects on the server ''{1}''.",
     118                    OsmApi.getOsmApi().getCapabilities().getMaxChangesetSize(),
     119                    OsmApi.getOsmApi().getBaseUrl()
     120                    );
     121        } else {
     122            msg1 = tr("The server reported that the current changeset was closed.<br>"
     123                    + "This is most likely because the changesets size exceeded the max. size<br>"
     124                    + "of {0} objects on the server ''{1}''.",
     125                    OsmApi.getOsmApi().getCapabilities().getMaxChangesetSize(),
     126                    OsmApi.getOsmApi().getBaseUrl()
     127                    );
     128        }
    118129        String msg2 = trn(
    119130                "There is {0} object left to upload.",
    120131                "There are {0} objects left to upload.",
     
    150161    }
    151162
    152163    /**
    153      * Handles a server changeset full response.
     164     * Handles a server changeset full response and the case that JOSM detects that a changeset is full while preparing an upload.
    154165     * <p>
    155      * Handles a server changeset full response by either aborting or opening a new changeset, if the
     166     * Handles a full changeset by either aborting or opening a new changeset, if the
    156167     * user requested it so.
     168     * @param source the source of the changeset exception
    157169     *
    158170     * @return true if the upload process should continue with the new changeset, false if the
    159171     *         upload should be interrupted
    160172     * @throws OsmTransferException "if something goes wrong."
    161173     */
    162     protected boolean handleChangesetFullResponse() throws OsmTransferException {
     174    protected boolean handleChangesetFullResponse(ChangesetClosedException.Source source) throws OsmTransferException {
    163175        if (processedPrimitives.size() == toUpload.getSize()) {
    164176            strategy.setPolicy(MaxChangesetSizeExceededPolicy.ABORT);
    165177            return false;
    166178        }
    167179        if (strategy.getPolicy() == null || strategy.getPolicy() == MaxChangesetSizeExceededPolicy.ABORT) {
    168             strategy.setPolicy(promptUserForPolicy());
     180            GuiHelper.runInEDTAndWait(() -> strategy.setPolicy(promptUserForPolicy(source)));
    169181        }
    170182        switch (strategy.getPolicy()) {
    171183        case AUTOMATICALLY_OPEN_NEW_CHANGESETS:
     
    282294                    }
    283295                    switch (e.getSource()) {
    284296                    case UPLOAD_DATA:
     297                    case PREPARE_FURTHER_UPLOAD:
    285298                        // Most likely the changeset is full. Try to recover and continue
    286299                        // with a new changeset, but let the user decide first.
    287                         if (handleChangesetFullResponse()) {
     300                        if (handleChangesetFullResponse(e.getSource())) {
    288301                            continue;
    289302                        }
    290303                        lastException = e;
     
    392405                if (strategy.getPolicy() == null)
    393406                    /* do nothing if unknown policy */
    394407                    return;
    395                 if (e.getSource() == ChangesetClosedException.Source.UPLOAD_DATA) {
     408                if (e.getSource() == ChangesetClosedException.Source.UPLOAD_DATA
     409                        || e.getSource() == ChangesetClosedException.Source.PREPARE_FURTHER_UPLOAD) {
    396410                    switch (strategy.getPolicy()) {
    397411                    case ABORT:
    398412                        break; /* do nothing - we return to map editing */
  • src/org/openstreetmap/josm/io/ChangesetClosedException.java

     
    4242        /**
    4343         * The exception was thrown when data was uploaded to the changeset. This most
    4444         * likely means that the servers capability limits for a changeset have been
    45          * exceeded.
     45         * exceeded. In this case the changeset itself is not closed, just the connection.
    4646         */
    4747        UPLOAD_DATA,
    4848        /**
     49         * The exception was thrown when the servers capability limits for a
     50         * changeset would be exceeded and further data should be uploaded.
     51         * It is assumed that the server would reject any further upload.
     52         */
     53        PREPARE_FURTHER_UPLOAD,
     54        /**
    4955         * The exception was thrown when we tried to close a changeset.  Probably the changeset
    5056         * already timed out on the server.
    5157         * @since 18283
  • src/org/openstreetmap/josm/io/OsmServerWriter.java

     
    165165                if (canceled) return;
    166166                int j = 0;
    167167                chunk.clear();
    168                 while (it.hasNext() && j < chunkSize && processed.size() + j < maxChunkSize) {
     168                final int oldChangesCount = api.getChangeset().getChangesCount();
     169                while (it.hasNext() && j < chunkSize && oldChangesCount + j < maxChunkSize) {
    169170                    j++;
    170171                    chunk.add(it.next());
    171172                }
    172                 progressMonitor.setCustomText(
    173                         trn("({0}/{1}) Uploading {2} object...",
    174                                 "({0}/{1}) Uploading {2} objects...",
    175                                 chunk.size(), i, numChunks, chunk.size()));
    176                 processed.addAll(api.uploadDiff(chunk, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)));
    177                 // see #23738: server will close CS if maximum changeset size was reached
    178                 if (processed.size() >= maxChunkSize) {
    179                     throw new ChangesetClosedException(api.getChangeset().getId(), Instant.now(), Source.UPLOAD_DATA);
     173                if (!chunk.isEmpty()) {
     174                    progressMonitor.setCustomText(
     175                            trn("({0}/{1}) Uploading {2} object...",
     176                                    "({0}/{1}) Uploading {2} objects...",
     177                                    chunk.size(), i, numChunks, chunk.size()));
     178                    processed.addAll(api.uploadDiff(chunk, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)));
    180179                }
     180                // see #23738: server will close the connection when a changeset is too large
     181                if (it.hasNext() && oldChangesCount + processed.size() >= maxChunkSize) {
     182                    throw new ChangesetClosedException(api.getChangeset().getId(), Instant.now(), Source.PREPARE_FURTHER_UPLOAD);
     183                }
    181184            }
    182185        } finally {
    183186            progressMonitor.finishTask();