I have a progress emitting request body..
class ProgressEmittingRequestBody(
private val delegate: RequestBody,
private val progressListener: ProgressListener,
) : RequestBody() {
override fun contentType(): MediaType? = delegate.contentType()
override fun contentLength(): Long {
try {
return delegate.contentLength()
} catch (e: IOException) {
e.printStackTrace()
}
return -1
}
override fun writeTo(sink: BufferedSink) {
val bufferedSink = CountingSink(sink).buffer()
delegate.writeTo(bufferedSink)
bufferedSink.flush()
}
private inner class CountingSink(
delegate: Sink
) : ForwardingSink(delegate) {
var bytesWritten = 0L
override fun write(source: Buffer, byteCount: Long) {
super.write(source, byteCount)
bytesWritten += byteCount
progressListener.onProgressUpdate(bytesWritten, contentLength())
}
}
}
But when I try to upload large files.. sometimes.. the following out of memory exception is thrown..
The custom http logging interceptor I am using is..
if (!logBody || requestBody == null) {
logger.log("--> END ${request.method}")
} else if (bodyHasUnknownEncoding(request.headers)) {
logger.log("--> END ${request.method} (encoded body omitted)")
} else if (requestBody.isDuplex()) {
logger.log("--> END ${request.method} (duplex request body omitted)")
} else if (requestBody.isOneShot()) {
logger.log("--> END ${request.method} (one-shot body omitted)")
} else {
if (requestBody.contentLength() == -1L) {
logger.log("Unknown content length.")
} else if (requestBody.contentLength() > 1024L * 1024) {
logger.log("Request body size exceeded ${1024 * 1024} bytes. Cannot log the request body.") //So that large source are not buffered.. Main change over here..
} else {
var buffer = Buffer()
requestBody.writeTo(buffer)
var gzippedLength: Long? = null
if ("gzip".equals(headers["Content-Encoding"], ignoreCase = true)) {
gzippedLength = buffer.size
GzipSource(buffer).use { gzippedResponseBody ->
buffer = Buffer()
buffer.writeAll(gzippedResponseBody)
}
}
val charset: Charset = requestBody.contentType().charset()
logger.log("")
if (!buffer.isProbablyUtf8()) {
logger.log(
"--> END ${request.method} (binary ${requestBody.contentLength()}-byte body omitted)"
)
} else if (gzippedLength != null) {
logger.log("--> END ${request.method} (${buffer.size}-byte, $gzippedLength-gzipped-byte body)")
} else {
logger.log(buffer.readString(charset))
logger.log("--> END ${request.method} (${requestBody.contentLength()}-byte body)")
}
}
}
If the out of memory exception was always happening, I would have trace the error.. But OOM is thrown for about 1 in 5 uploads and I am not able to track the error..
What am I doing wrong?