Ignore:
Timestamp:
03/14/13 13:30:06 (11 years ago)
Author:
oschonef
Message:
  • buffer output as long as possible (helps to gracefully recover from error conditions with fatal diagnostic)
  • make buffer size a configuration parameter
  • more debugging information in case of (recoverable) error condition with fatal diagnostics
File:
1 edited

Legend:

Unmodified
Added
Removed
  • SRUServer/trunk/src/main/java/eu/clarin/sru/server/SRUServer.java

    r2692 r2698  
    1717package eu.clarin.sru.server;
    1818
     19import java.io.FilterOutputStream;
    1920import java.io.IOException;
    2021import java.io.OutputStream;
     
    6566    static final String RESPONSE_ENCODING = "utf-8";
    6667    private static final String RESPONSE_CONTENT_TYPE = "application/xml";
    67     private static final int RESPONSE_BUFFER_SIZE = 64 * 1024;
    6868    private static final Logger logger =
    6969            LoggerFactory.getLogger(SRUServer.class);
     
    116116            response.setStatus(HttpServletResponse.SC_OK);
    117117            // make sure we can reset the stream later in case of error ...
    118             response.setBufferSize(RESPONSE_BUFFER_SIZE);
    119 
     118            response.setBufferSize(config.getResponseBufferSize());
    120119            try {
    121120                if (req.checkParameters()) {
     
    135134                    SRUXMLStreamWriter out =
    136135                        createXMLStreamWriter(response.getOutputStream(),
    137                                 SRURecordPacking.XML, req.getIndentResponse());
     136                                SRURecordPacking.XML, false,
     137                                req.getIndentResponse());
    138138                    writeFatalError(out, req, req.getDiagnostics());
    139139                }
     
    150150        } catch (SRUException e) {
    151151            if (!response.isCommitted()) {
     152                if (logger.isInfoEnabled()) {
     153                    final String message = e.getDiagnostic().getMessage();
     154                    if (message != null) {
     155                        logger.info("Sending fatal diagnostic '{}{}' with " +
     156                                "message '{}'",
     157                                new Object[] {
     158                                        SRUConstants.SRU_DIAGNOSTIC_URI_PREFIX,
     159                                        e.getDiagnostic().getCode(),
     160                                        message
     161                                });
     162                    } else {
     163                        logger.info("Sending fatal diagnostic '{}{}'",
     164                                SRUConstants.SRU_DIAGNOSTIC_URI_PREFIX,
     165                                e.getDiagnostic().getCode());
     166                    }
     167                    logger.debug("Fatal diagnostic was caused by " +
     168                            "this exception", e);
     169                }
    152170                response.resetBuffer();
    153171                try {
     
    160178                    SRUXMLStreamWriter out =
    161179                            createXMLStreamWriter(response.getOutputStream(),
    162                                     SRURecordPacking.XML,
     180                                    SRURecordPacking.XML, false,
    163181                                    req.getIndentResponse());
    164182                    writeFatalError(out, req, diagnostics);
     
    168186                }
    169187            } else {
     188                /*
     189                 * The servlet already flushed the output buffer, so cannot
     190                 * degrade gracefully anymore and, unfortunately, will produce
     191                 * ill-formed XML output.
     192                 * Increase the response buffer size, if you want to avoid
     193                 * this (at the cost of memory).
     194                 */
    170195                logger.error("A fatal error occurred, but the response was "
    171                         + "already committed", e);
     196                        + "already committed. Unable to recover gracefully.", e);
    172197            }
    173198        }
     
    188213                    createXMLStreamWriter(response.getOutputStream(),
    189214                                          request.getRecordPacking(),
     215                                          true,
    190216                                          request.getIndentResponse());
    191217
     
    238264                    createXMLStreamWriter(response.getOutputStream(),
    239265                                          request.getRecordPacking(),
     266                                          true,
    240267                                          request.getIndentResponse());
    241268
     
    364391                    createXMLStreamWriter(response.getOutputStream(),
    365392                                          request.getRecordPacking(),
     393                                          true,
    366394                                          request.getIndentResponse());
    367395
     
    10441072
    10451073    private SRUXMLStreamWriter createXMLStreamWriter(OutputStream out,
    1046             SRURecordPacking recordPacking, int indent) throws SRUException {
     1074            SRURecordPacking recordPacking, boolean skipFlush, int indent)
     1075            throws SRUException {
    10471076        try {
    1048             return new SRUXMLStreamWriter(out, writerFactory, recordPacking,
    1049                     indent);
     1077            if (skipFlush) {
     1078                /*
     1079                 * Add a FilterOutputStream to delay flush() as long as
     1080                 * possible. Doing so, enabled us to send an appropriate SRU
     1081                 * diagnostic in case an error occurs during the serialization
     1082                 * of the response.
     1083                 * Of course, if an error occurs when the Servlet response
     1084                 * buffer already had been flushed, because it was to large,
     1085                 * we cannot fail gracefully and we will produce ill-formed
     1086                 * XML output.
     1087                 */
     1088                out = new FilterOutputStream(out) {
     1089                    @Override
     1090                    public void flush() throws IOException {
     1091                    }
     1092
     1093
     1094                    @Override
     1095                    public void close() throws IOException {
     1096                        super.flush();
     1097                        super.close();
     1098                    }
     1099                };
     1100            }
     1101            return new SRUXMLStreamWriter(out, writerFactory,
     1102                    recordPacking, indent);
    10501103        } catch (Exception e) {
    10511104            throw new SRUException(SRUConstants.SRU_GENERAL_SYSTEM_ERROR,
Note: See TracChangeset for help on using the changeset viewer.