Skip to content

Commit

Permalink
Added logic to delete orphaned attachments on startup
Browse files Browse the repository at this point in the history
  • Loading branch information
oxtoacart committed Apr 27, 2021
1 parent 4d9de90 commit 99e9083
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,34 @@ class MessagingTest : BaseMessagingTest() {
}
}

@Test
fun testOrphanedAttachment() {
testInCoroutine {
newDB.use { dogDB ->
newMessaging(dogDB, "dog").with { dog ->
val attachment = dog.createAttachment(
"text/plain",
5,
"hello".byteInputStream(Charsets.UTF_8)
)
assertTrue(
File(attachment.encryptedFilePath).exists(),
"attachment file should have been created"
)
dog.close()
// wait a couple of seconds
delay(2000)
newMessaging(dogDB, "dog").with { dog2 ->
assertFalse(
File(attachment.encryptedFilePath).exists(),
"orphaned attachment file should have been deleted"
)
}
}
}
}
}

@Test
fun testDeliveryStatus() {
testInCoroutine {
Expand Down Expand Up @@ -1015,6 +1043,7 @@ class MessagingTest : BaseMessagingTest() {
clientTimeoutMillis: Long = 5L.secondsToMillis,
failedSendRetryDelayMillis: Long = 100,
stopSendRetryAfterMillis: Long = 5L.minutesToMillis,
orphanedAttachmentCutoffSeconds: Int = 1,
): Messaging {
return Messaging(
db,
Expand All @@ -1031,6 +1060,7 @@ class MessagingTest : BaseMessagingTest() {
maxRedialDelayMillis = 500L,
failedSendRetryDelayMillis = failedSendRetryDelayMillis,
stopSendRetryAfterMillis = stopSendRetryAfterMillis,
orphanedAttachmentCutoffSeconds = orphanedAttachmentCutoffSeconds,
name = name
)
}
Expand Down
48 changes: 48 additions & 0 deletions messaging/src/main/java/io/lantern/messaging/Messaging.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import java.security.SecureRandom
import java.util.UUID
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicReference
import kotlin.collections.HashSet

/**
* This exception indicates that a message was received from an unknown sender (i.e. someone not in
Expand Down Expand Up @@ -58,6 +59,7 @@ class Messaging(
stopSendRetryAfterMillis: Long = 24L.hoursToMillis,
numInitialPreKeysToRegister: Int = 5,
private val defaultMessagesDisappearAfterSeconds: Int = 86400, // 1 day
private val orphanedAttachmentCutoffSeconds: Int = 86400, // 1 day
internal val name: String = "messaging",
defaultConfiguration: Messages.Configuration = Messages.Configuration.newBuilder()
.setMaxAttachmentSize(100000000).build()
Expand Down Expand Up @@ -150,6 +152,10 @@ class Messaging(
// this also has the welcome side effect of starting an authenticated client, which we need
// in order to receive messages
cryptoWorker.registerPreKeys(numInitialPreKeysToRegister)

// on startup, go through all attachments older than a day and delete any that are not in
// the database
deleteOrphanedAttachments()
}

fun setMyDisplayName(displayName: String) {
Expand Down Expand Up @@ -639,6 +645,48 @@ class Messaging(
}
}

private fun deleteOrphanedAttachments() {
// first build a set of all known attachment paths
var knownAttachmentPaths = db
.list<Model.StoredMessage>(Schema.PATH_MESSAGES.path("%"))
.flatMap { msg ->
msg.value.attachmentsMap.values.map { attachment -> attachment.encryptedFilePath }
}
// the walk the attachments directory tree and delete any old files with no known attachment
// path
deleteOrphanedAttachments(
now,
(orphanedAttachmentCutoffSeconds * 1000).toLong(),
HashSet(knownAttachmentPaths),
attachmentsDirectory
)
}

private fun deleteOrphanedAttachments(
now: Long,
cutoffMillis: Long,
knownAttachmentPaths: HashSet<String>,
dir: File
) {
if (dir.exists()) {
val files = dir.listFiles()
for (i in files.indices) {
val file = files[i]
if (file.isDirectory) {
deleteOrphanedAttachments(now, cutoffMillis, knownAttachmentPaths, file)
} else {
if (!knownAttachmentPaths.contains(file.absolutePath)) {
val fileOldEnough = now - file.lastModified() > cutoffMillis
if (fileOldEnough) {
logger.debug("deleting orphaned attachment ${file.absolutePath}")
file.delete()
}
}
}
}
}
}

override fun close() {
try {
cryptoWorker.close()
Expand Down

0 comments on commit 99e9083

Please sign in to comment.