in app/helpers/MetadataHelper.scala [106:158]
def getOMFileMd5(f:MxsObject, maxAttempts:Int=2):Try[String] = {
def lookup(attempt:Int=1):Try[String] = {
if(attempt>maxAttempts) return Failure(new RuntimeException(s"Could not get valid checksum after $attempt tries"))
val view = f.getAttributeView
val result = Try {
logger.debug(s"getting result for ${f.getId}...")
val buf = ByteBuffer.allocate(16)
view.read("__mxs__calc_md5", buf)
buf
}
result match {
case Failure(err:TaggedIOException)=>
if(err.getError==302){
logger.warn(s"Got 302 (server busy) from appliance, retrying after delay")
Thread.sleep(500)
lookup(attempt+1)
} else {
Failure(err)
}
case Failure(err:java.io.IOException)=>
if(err.getMessage.contains("error 302")){
logger.warn(err.getMessage)
logger.warn(s"Got an error containing 302 string, assuming server busy, retrying after delay")
Thread.sleep(500)
lookup(attempt+1)
} else {
Failure(err)
}
case Failure(otherError)=>Failure(otherError)
case Success(buffer)=>
val arr = buffer.array()
if(! isNonNull(arr)) {
logger.info(s"Empty string returned for file MD5 on attempt $attempt, assuming still calculating. Will retry...")
Thread.sleep(1000) //this feels nasty but without resorting to actors i can't think of an elegant way
//to delay and re-call in a non-blocking way
lookup(attempt + 1)
} else {
val converted = Hex.encodeHexString(arr)
if (converted.length == 32)
Success(converted)
else {
logger.warn(s"Returned checksum $converted is wrong length (${converted.length}; should be 32).")
Thread.sleep(1500)
lookup(attempt + 1)
}
}
}
}
lookup()
}