package co.id.datacomsolusindo.ipphonebridge import kotlinx.coroutines.* import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import java.time.LocalDateTime import java.time.format.DateTimeFormatter import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentMap import kotlin.system.measureTimeMillis object ClientHolder { private val mutexSucReq = Mutex() private val clientMap: ConcurrentMap by lazy { ConcurrentHashMap() } private suspend fun massiveRun(action: suspend () -> Unit) { measureTimeMillis { coroutineScope { // sc launch { action() } } } } fun removeBySessionId(sessionId: String?) { clientMap.entries.filter { it.value.sessionId == sessionId }.forEach { clientMap.remove(it.key) //unsubscribe incoming data } } fun put(key: String, client: Client) { clientMap.getOrPut(key) { client } //subscribe incoming data } fun get() = clientMap fun addFailedRequest(clNum: String) { runBlocking { withContext(Dispatchers.Default) { massiveRun { mutexSucReq.withLock { val cl = clientMap[clNum] if (cl != null) { cl.lastRequest = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")) cl.reqFailed += 1 } } } } } } fun addSuccessRequest(clNum: String, duration: Double) { runBlocking { withContext(Dispatchers.Default) { massiveRun { // protect each increment with lock mutexSucReq.withLock { val cl = clientMap[clNum] if (cl != null) { cl.lastRequest = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")) cl.avgReqSuccessTime = ((cl.avgReqSuccessTime * cl.reqSuccess) + duration) / (cl.reqSuccess + 1) cl.reqSuccess += 1 } } } } } } }