Skip to content

Instantly share code, notes, and snippets.

@kenoir
Created September 11, 2019 09:14
Show Gist options
  • Save kenoir/4593cb9a960b93b95560f283e2e58a1e to your computer and use it in GitHub Desktop.
Save kenoir/4593cb9a960b93b95560f283e2e58a1e to your computer and use it in GitHub Desktop.
import org.apache.commons.io.IOUtils
import uk.ac.wellcome.storage.streaming.Codec
import scala.util.{Success, Try}
trait IdempotentVersionedWritable[Id, V, T]
extends Writable[Version[Id, V], T]
with Readable[Version[Id, V], T] {
implicit val codec: Codec[T]
abstract override def put(id: Version[Id, V])(t: T): WriteEither = {
super.put(id)(t) match {
case Right(identifiedT) => Right(identifiedT)
case Left(originalError: VersionAlreadyExistsError) => for {
putStream <- codec.toStream(t)
retrieved <- get(id) match {
case Right(result) => Right(result)
case Left(readError) => Left(IdempotentCheckWriteError(readError))
}
getStream <- codec.toStream(retrieved.identifiedT)
tryEquals <- Try(IOUtils.contentEquals(putStream, getStream)) match {
case Success(equality) => Right(equality)
case Failure(err) => Left(IOExceptionWriteError(err))
}
result <- if(tryEquals) {
Right(Identified(id, t))
} else {
Left(originalError)
}
} yield result
case Left(err) => Left(err)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment