SendMessage: plumb a guid through to uniquely identify a pending message
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
package net.buzzert.kordophone.backend.events
|
||||
|
||||
import net.buzzert.kordophone.backend.model.Conversation
|
||||
import net.buzzert.kordophone.backend.model.GUID
|
||||
import net.buzzert.kordophone.backend.model.Message
|
||||
|
||||
data class MessageDeliveredEvent(
|
||||
val guid: GUID,
|
||||
val message: Message,
|
||||
val conversation: Conversation,
|
||||
)
|
||||
|
||||
@@ -3,6 +3,8 @@ package net.buzzert.kordophone.backend.model
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import java.util.Date
|
||||
|
||||
typealias GUID = String
|
||||
|
||||
data class Conversation(
|
||||
@SerializedName("date")
|
||||
val date: Date,
|
||||
@@ -20,5 +22,5 @@ data class Conversation(
|
||||
val lastMessagePreview: String,
|
||||
|
||||
@SerializedName("guid")
|
||||
val guid: String,
|
||||
val guid: GUID,
|
||||
)
|
||||
|
||||
@@ -8,7 +8,7 @@ data class Message(
|
||||
val text: String,
|
||||
|
||||
@SerializedName("guid")
|
||||
val guid: String,
|
||||
val guid: GUID,
|
||||
|
||||
@SerializedName("sender")
|
||||
val sender: String?, // optional: nil means "from me"
|
||||
|
||||
@@ -5,17 +5,25 @@ import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import net.buzzert.kordophone.backend.events.MessageDeliveredEvent
|
||||
import net.buzzert.kordophone.backend.model.Conversation
|
||||
import net.buzzert.kordophone.backend.model.GUID
|
||||
import net.buzzert.kordophone.backend.model.Message
|
||||
import java.net.URL
|
||||
import java.util.Queue
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.ArrayBlockingQueue
|
||||
|
||||
const val REPO_LOG: String = "ChatRepository"
|
||||
|
||||
class ChatRepository(private val apiInterface: APIInterface) {
|
||||
public val messageDeliveredChannel = Channel<MessageDeliveredEvent>()
|
||||
val messageDeliveredChannel = Channel<MessageDeliveredEvent>()
|
||||
|
||||
private val outgoingMessageQueue: ArrayBlockingQueue<Pair<Message, Conversation>> = ArrayBlockingQueue(16)
|
||||
private data class OutgoingMessageInfo (
|
||||
val message: Message,
|
||||
val conversation: Conversation,
|
||||
val guid: GUID,
|
||||
)
|
||||
|
||||
private val outgoingMessageQueue: ArrayBlockingQueue<OutgoingMessageInfo> = ArrayBlockingQueue(16)
|
||||
private var outgoingMessageThread: Thread? = null
|
||||
|
||||
suspend fun getVersion(): String {
|
||||
@@ -30,14 +38,18 @@ class ChatRepository(private val apiInterface: APIInterface) {
|
||||
return apiInterface.getMessages(conversation.guid).body()!!
|
||||
}
|
||||
|
||||
suspend fun enqueueOutgoingMessage(message: Message, conversation: Conversation) {
|
||||
Log.d(REPO_LOG, "Enqueuing outgoing message: $message")
|
||||
outgoingMessageQueue.add(Pair(message, conversation))
|
||||
suspend fun enqueueOutgoingMessage(message: Message, conversation: Conversation): GUID {
|
||||
val guid = UUID.randomUUID().toString()
|
||||
|
||||
Log.d(REPO_LOG, "Enqueuing outgoing message: $message ($guid)")
|
||||
outgoingMessageQueue.add(OutgoingMessageInfo(message, conversation, guid))
|
||||
|
||||
if (outgoingMessageThread == null) {
|
||||
outgoingMessageThread = Thread { outgoingMessageQueueMain() }
|
||||
outgoingMessageThread?.start()
|
||||
}
|
||||
|
||||
return guid
|
||||
}
|
||||
|
||||
// - private
|
||||
@@ -47,7 +59,10 @@ class ChatRepository(private val apiInterface: APIInterface) {
|
||||
while (true) {
|
||||
val outgoingMessageRequest = outgoingMessageQueue.poll()?.let {
|
||||
runBlocking {
|
||||
val (message, conversation) = it
|
||||
val guid = it.guid
|
||||
val message = it.message
|
||||
val conversation = it.conversation
|
||||
|
||||
Log.d(REPO_LOG, "Sending message to $conversation: $message")
|
||||
|
||||
val result = apiInterface.sendMessage(
|
||||
@@ -60,7 +75,7 @@ class ChatRepository(private val apiInterface: APIInterface) {
|
||||
|
||||
if (result.isSuccessful) {
|
||||
Log.d(REPO_LOG, "Successfully sent message.")
|
||||
messageDeliveredChannel.send(MessageDeliveredEvent(message, conversation))
|
||||
messageDeliveredChannel.send(MessageDeliveredEvent(guid, message, conversation))
|
||||
} else {
|
||||
Log.e(REPO_LOG, "Error sending message. Enqueuing for retry.")
|
||||
outgoingMessageQueue.add(it)
|
||||
|
||||
@@ -78,9 +78,10 @@ class BackendTests {
|
||||
sender = null,
|
||||
)
|
||||
|
||||
repository.enqueueOutgoingMessage(outgoingMessage, conversation)
|
||||
val guid = repository.enqueueOutgoingMessage(outgoingMessage, conversation)
|
||||
|
||||
val event = repository.messageDeliveredChannel.receive()
|
||||
assertEquals(event.guid, guid)
|
||||
assertEquals(event.message.text, outgoingMessage.text)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user