Fix sending buffered messages

This commit is contained in:
max-klaus 2020-01-26 21:35:07 +03:00
parent e6c0d55c95
commit c64b29a2a7
2 changed files with 55 additions and 43 deletions

View file

@ -9,6 +9,7 @@ import android.text.SpannableStringBuilder
import android.text.style.ForegroundColorSpan
import net.osmand.PlatformUtil
import net.osmand.telegram.helpers.OsmandAidlHelper
import net.osmand.telegram.helpers.ShareLocationHelper.Companion.MAX_MESSAGES_IN_TDLIB_PER_CHAT
import net.osmand.telegram.helpers.ShowLocationHelper
import net.osmand.telegram.helpers.TelegramHelper
import net.osmand.telegram.utils.*
@ -22,6 +23,7 @@ import java.util.*
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentLinkedQueue
import kotlin.collections.ArrayList
import kotlin.math.max
val ADDITIONAL_ACTIVE_TIME_VALUES_SEC = listOf(15 * 60L, 30 * 60L, 60 * 60L, 180 * 60L)
@ -529,6 +531,7 @@ class TelegramSettings(private val app: TelegramApplication) {
var initializing = false
var sendChatsErrors = false
val chatsCount = shareChatsInfo.size
shareChatsInfo.forEach { (_, shareInfo) ->
val initTime = (currentTime - shareInfo.start) < SHARING_INITIALIZATION_TIME
var initSending = false
@ -537,15 +540,16 @@ class TelegramSettings(private val app: TelegramApplication) {
if (initTime && initSending) {
initializing = true
} else {
val textSharingError = !shareInfo.lastTextMessageHandled && currentTime - shareInfo.lastSendTextMessageTime > WAITING_TDLIB_TIME
val mapSharingError = !shareInfo.lastMapMessageHandled && currentTime - shareInfo.lastSendMapMessageTime > WAITING_TDLIB_TIME
val maxWaitingTime = WAITING_TDLIB_TIME * MAX_MESSAGES_IN_TDLIB_PER_CHAT * max(1, chatsCount)
val textSharingError = !shareInfo.lastTextMessageHandled && currentTime - shareInfo.lastSendTextMessageTime > maxWaitingTime
val mapSharingError = !shareInfo.lastMapMessageHandled && currentTime - shareInfo.lastSendMapMessageTime > maxWaitingTime
if (shareInfo.hasSharingError
|| (shareTypeValue == SHARE_TYPE_MAP_AND_TEXT && (textSharingError || mapSharingError))
|| textSharingError && (shareTypeValue == SHARE_TYPE_TEXT)
|| mapSharingError && (shareTypeValue == SHARE_TYPE_MAP)
) {
sendChatsErrors = true
locationTime = Math.max(shareInfo.lastTextSuccessfulSendTime, shareInfo.lastMapSuccessfulSendTime)
locationTime = max(shareInfo.lastTextSuccessfulSendTime, shareInfo.lastMapSuccessfulSendTime)
chatsIds.add(shareInfo.chatId)
}
}
@ -1455,6 +1459,7 @@ class TelegramSettings(private val app: TelegramApplication) {
var additionalActiveTime = ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0]
var lastMapMessageHandled = false
var lastTextMessageHandled = false
var lastBufferCheckTime = -1L
fun getNextAdditionalActiveTime(): Long {
var index = ADDITIONAL_ACTIVE_TIME_VALUES_SEC.indexOf(additionalActiveTime)
@ -1469,6 +1474,13 @@ class TelegramSettings(private val app: TelegramApplication) {
return userSetLivePeriod - ((System.currentTimeMillis() / 1000) - start)
}
fun isPendingMessagesLimitReached() =
pendingTdLibText >= MAX_MESSAGES_IN_TDLIB_PER_CHAT || pendingTdLibMap >= MAX_MESSAGES_IN_TDLIB_PER_CHAT
fun isPendingTextMessagesLimitReached() = pendingTdLibText >= MAX_MESSAGES_IN_TDLIB_PER_CHAT
fun isPendingMapMessagesLimitReached() = pendingTdLibMap >= MAX_MESSAGES_IN_TDLIB_PER_CHAT
companion object {
internal const val CHAT_ID_KEY = "chatId"

View file

@ -15,24 +15,25 @@ import org.json.JSONObject
private const val USER_SET_LIVE_PERIOD_DELAY_MS = 5000 // 5 sec
private const val SENT_LOCATIONS_INTERVAL_TIME_MS = 4000 // 4 sec
private const val MIN_MESSAGE_SENDING_INTERVAL_MS = 1000 // 1 sec
private const val MIN_MESSAGES_BUFFER_CHECK_INTERVAL_MS = 800 // 0.8 sec
class ShareLocationHelper(private val app: TelegramApplication) {
private val log = PlatformUtil.getLog(ShareLocationHelper::class.java)
var sharingLocation: Boolean = false
var sharingLocation = false
private set
var duration: Long = 0
var duration = 0L
private set
var distance: Int = 0
var distance = 0
private set
var lastLocationUpdateTime: Long = 0
var lastLocationUpdateTime = 0L
var lastLocationSentTime: Long = 0
private var lastShareLocationMessageTime = 0L
var lastLocation: Location? = null
set(value) {
@ -121,29 +122,32 @@ class ShareLocationHelper(private val app: TelegramApplication) {
fun checkAndSendBufferMessages() {
log.debug("checkAndSendBufferMessages")
var bufferedMessagesFull = false
var pendingMessagesLimitReached = false
app.settings.getChatsShareInfo().forEach { (chatId, shareInfo) ->
checkAndSendBufferMessagesToChat(chatId)
if (shareInfo.pendingTdLibText >= MAX_MESSAGES_IN_TDLIB_PER_CHAT || shareInfo.pendingTdLibMap >= MAX_MESSAGES_IN_TDLIB_PER_CHAT) {
bufferedMessagesFull = true
checkAndSendBufferMessagesToChat(chatId, true)
if (shareInfo.isPendingMessagesLimitReached()) {
pendingMessagesLimitReached = true
}
}
if (bufferedMessagesFull) {
if (pendingMessagesLimitReached) {
checkNetworkType()
}
}
fun checkAndSendBufferMessagesToChat(chatId: Long) {
fun checkAndSendBufferMessagesToChat(chatId: Long, forced: Boolean = false): Int {
val shareChatsInfo = app.settings.getChatsShareInfo()
val shareInfo = shareChatsInfo[chatId]
val chatsCounts = shareChatsInfo.size
val currentTime = System.currentTimeMillis()
if (shareInfo != null && currentTime - lastLocationSentTime > chatsCounts * SENT_LOCATIONS_INTERVAL_TIME_MS) {
if (shareInfo != null) {
val currentTime = System.currentTimeMillis()
if (currentTime - shareInfo.lastBufferCheckTime < MIN_MESSAGES_BUFFER_CHECK_INTERVAL_MS && !forced) {
return app.locationMessages.getBufferedMessagesCountForChat(chatId)
}
shareInfo.lastBufferCheckTime = currentTime
app.locationMessages.getBufferedTextMessagesForChat(chatId).take(MAX_MESSAGES_IN_TDLIB_PER_CHAT).forEach {
if (shareInfo.pendingTdLibText < MAX_MESSAGES_IN_TDLIB_PER_CHAT) {
if (!shareInfo.isPendingTextMessagesLimitReached()) {
if (it.deviceName.isEmpty()) {
if (!shareInfo.pendingTextMessage && shareInfo.currentTextMessageId != -1L) {
lastLocationSentTime = System.currentTimeMillis()
val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, it, app)
app.telegramHelper.editTextLocation(shareInfo, content)
app.locationMessages.removeBufferedMessage(it)
@ -154,10 +158,9 @@ class ShareLocationHelper(private val app: TelegramApplication) {
}
}
app.locationMessages.getBufferedMapMessagesForChat(chatId).take(MAX_MESSAGES_IN_TDLIB_PER_CHAT).forEach {
if (shareInfo.pendingTdLibMap < MAX_MESSAGES_IN_TDLIB_PER_CHAT) {
if (!shareInfo.isPendingMapMessagesLimitReached()) {
if (it.deviceName.isEmpty()) {
if (!shareInfo.pendingMapMessage && shareInfo.currentMapMessageId != -1L) {
lastLocationSentTime = System.currentTimeMillis()
app.telegramHelper.editMapLocation(shareInfo, it)
app.locationMessages.removeBufferedMessage(it)
}
@ -166,7 +169,9 @@ class ShareLocationHelper(private val app: TelegramApplication) {
}
}
}
return app.locationMessages.getBufferedMessagesCountForChat(chatId)
}
return 0
}
fun startSharingLocation() {
@ -219,44 +224,44 @@ class ShareLocationHelper(private val app: TelegramApplication) {
val time = location.time
val isBot = app.settings.currentSharingMode != userId.toString()
val deviceName = if (isBot) app.settings.currentSharingMode else ""
var bufferedMessagesFull = false
val chatsCounts = chatsShareInfo.size
var pendingMessagesLimitReached = false
val currentTime = System.currentTimeMillis()
app.locationMessages.addMyLocationMessage(location)
if (currentTime - lastLocationSentTime <= chatsCounts * SENT_LOCATIONS_INTERVAL_TIME_MS) {
if (currentTime - lastShareLocationMessageTime < MIN_MESSAGE_SENDING_INTERVAL_MS) {
return
}
lastShareLocationMessageTime = currentTime
chatsShareInfo.values.forEach { shareInfo ->
if (shareInfo.pendingTdLibText >= MAX_MESSAGES_IN_TDLIB_PER_CHAT || shareInfo.pendingTdLibMap >= MAX_MESSAGES_IN_TDLIB_PER_CHAT) {
bufferedMessagesFull = true
val hasBufferedMessages = checkAndSendBufferMessagesToChat(shareInfo.chatId) > 0
if (shareInfo.isPendingMessagesLimitReached()) {
pendingMessagesLimitReached = true
}
checkAndSendBufferMessagesToChat(shareInfo.chatId)
when (app.settings.shareTypeValue) {
SHARE_TYPE_MAP -> {
val message = BufferMessage(shareInfo.chatId, latitude, longitude, altitude, speed, accuracy, bearing, time, LocationMessages.TYPE_MAP, deviceName)
prepareMapMessage(shareInfo, message, isBot)
prepareMapMessage(shareInfo, message, isBot, hasBufferedMessages)
}
SHARE_TYPE_TEXT -> {
val message = BufferMessage(shareInfo.chatId, latitude, longitude, altitude, speed, accuracy, bearing, time, LocationMessages.TYPE_TEXT, deviceName)
prepareTextMessage(shareInfo, message, isBot)
prepareTextMessage(shareInfo, message, isBot, hasBufferedMessages)
}
SHARE_TYPE_MAP_AND_TEXT -> {
val messageMap = BufferMessage(shareInfo.chatId, latitude, longitude, altitude, speed, accuracy, bearing, time, LocationMessages.TYPE_MAP, deviceName)
val messageText = BufferMessage(shareInfo.chatId, latitude, longitude, altitude, speed, accuracy, bearing, time, LocationMessages.TYPE_TEXT, deviceName)
prepareMapMessage(shareInfo, messageMap, isBot)
prepareTextMessage(shareInfo, messageText, isBot)
prepareMapMessage(shareInfo, messageMap, isBot, hasBufferedMessages)
prepareTextMessage(shareInfo, messageText, isBot, hasBufferedMessages)
}
}
}
if (bufferedMessagesFull) {
if (pendingMessagesLimitReached) {
checkNetworkType()
}
}
private fun prepareTextMessage(shareInfo: TelegramSettings.ShareChatInfo, message: BufferMessage, isBot: Boolean) {
private fun prepareTextMessage(shareInfo: TelegramSettings.ShareChatInfo, message: BufferMessage, isBot: Boolean, hasBufferedMessages: Boolean) {
log.debug("prepareTextMessage $message")
if (shareInfo.currentTextMessageId == -1L) {
if (shareInfo.pendingTextMessage) {
@ -265,7 +270,6 @@ class ShareLocationHelper(private val app: TelegramApplication) {
if (isBot) {
sendLocationToBot(message, shareInfo, SHARE_TYPE_TEXT)
} else {
lastLocationSentTime = System.currentTimeMillis()
val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, message, app)
app.telegramHelper.sendNewTextLocation(shareInfo, content)
}
@ -278,8 +282,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
app.locationMessages.addBufferedMessage(message)
}
} else {
if (shareInfo.pendingTdLibText < MAX_MESSAGES_IN_TDLIB_PER_CHAT) {
lastLocationSentTime = System.currentTimeMillis()
if (!shareInfo.isPendingTextMessagesLimitReached() && !hasBufferedMessages) {
val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, message, app)
app.telegramHelper.editTextLocation(shareInfo, content)
} else {
@ -289,7 +292,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
}
}
private fun prepareMapMessage(shareInfo: TelegramSettings.ShareChatInfo, message: BufferMessage, isBot: Boolean) {
private fun prepareMapMessage(shareInfo: TelegramSettings.ShareChatInfo, message: BufferMessage, isBot: Boolean, hasBufferedMessages: Boolean) {
log.debug("prepareMapMessage $message")
if (shareInfo.currentMapMessageId == -1L) {
if (shareInfo.pendingMapMessage) {
@ -302,7 +305,6 @@ class ShareLocationHelper(private val app: TelegramApplication) {
app.locationMessages.addBufferedMessage(message)
}
} else {
lastLocationSentTime = System.currentTimeMillis()
app.telegramHelper.sendNewMapLocation(shareInfo, message)
}
}
@ -314,8 +316,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
app.locationMessages.addBufferedMessage(message)
}
} else {
if (shareInfo.pendingTdLibMap < MAX_MESSAGES_IN_TDLIB_PER_CHAT) {
lastLocationSentTime = System.currentTimeMillis()
if (!shareInfo.isPendingMapMessagesLimitReached() && !hasBufferedMessages) {
app.telegramHelper.editMapLocation(shareInfo, message)
} else {
app.locationMessages.addBufferedMessage(message)
@ -344,7 +345,6 @@ class ShareLocationHelper(private val app: TelegramApplication) {
} else if (shareType == SHARE_TYPE_MAP) {
shareInfo.lastSendMapMessageTime = (System.currentTimeMillis() / 1000).toInt()
}
lastLocationSentTime = System.currentTimeMillis()
AndroidNetworkUtils.sendRequestAsync(app, url, null, "Send Location", false, false,
object : AndroidNetworkUtils.OnRequestResultListener {
override fun onResult(result: String?) {
@ -408,7 +408,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
companion object {
const val MAX_MESSAGES_IN_TDLIB_PER_CHAT = 10
const val MAX_MESSAGES_IN_TDLIB_PER_CHAT = 5
// min and max values for the UI
const val MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC = TelegramHelper.MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC - 1