mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2025-12-18 04:20:19 -07:00
Improved packet writing, should improve responsiveness when many players are online
This commit is contained in:
parent
e8c22249a2
commit
cc1eca5237
2 changed files with 19 additions and 45 deletions
|
|
@ -1,21 +1,15 @@
|
|||
package core.net.packet
|
||||
|
||||
import core.api.TickListener
|
||||
import core.api.tryPop
|
||||
import core.net.packet.out.*
|
||||
import core.tools.SystemLogger
|
||||
import java.lang.IndexOutOfBoundsException
|
||||
import java.io.PrintWriter
|
||||
import java.io.StringWriter
|
||||
import java.util.*
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
import kotlin.NoSuchElementException
|
||||
|
||||
class PacketWriteQueue : TickListener {
|
||||
override fun tick() {
|
||||
flush()
|
||||
}
|
||||
|
||||
class PacketWriteQueue {
|
||||
companion object {
|
||||
private val queueLock = ReentrantLock()
|
||||
private val packetsToQueue = LinkedList<QueuedPacket<*>?>()
|
||||
private val packetsToWrite = LinkedList<QueuedPacket<*>?>()
|
||||
|
||||
@JvmStatic
|
||||
|
|
@ -33,46 +27,24 @@ class PacketWriteQueue : TickListener {
|
|||
|
||||
@JvmStatic
|
||||
fun <T> push(packet: OutgoingPacket<T>, context: T) {
|
||||
if (queueLock.isHeldByCurrentThread)
|
||||
packetsToQueue.add(QueuedPacket(packet, context))
|
||||
else
|
||||
packetsToWrite.add(QueuedPacket(packet, context))
|
||||
packetsToWrite.add(QueuedPacket(packet, context))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun flush() {
|
||||
queueLock.lock()
|
||||
|
||||
var hasEnded = false
|
||||
while (!hasEnded) {
|
||||
var countThisCycle = packetsToWrite.size
|
||||
val sw = StringWriter()
|
||||
val pw = PrintWriter(sw)
|
||||
while (countThisCycle-- > 0) {
|
||||
val pkt = packetsToWrite.tryPop(null) ?: continue
|
||||
try {
|
||||
val packet = packetsToWrite.pop()
|
||||
write(packet?.out ?: continue, packet.context ?: continue)
|
||||
} catch (e: NoSuchElementException) {
|
||||
hasEnded = true
|
||||
}
|
||||
}
|
||||
|
||||
if (packetsToWrite.isNotEmpty()) {
|
||||
SystemLogger.logWarn(this::class.java, "Packet queue was NOT empty! Remaining packets: ${packetsToWrite.size}")
|
||||
try {
|
||||
for (pkt: QueuedPacket<*>? in packetsToWrite) SystemLogger.logWarn(this::class.java, "${pkt?.out?.javaClass?.simpleName ?: "NULL"} <- ${pkt?.context ?: "NULL"}")
|
||||
} catch (ignored: NullPointerException) {
|
||||
//do nothing, we don't care, this can happen when everything is working as intended.
|
||||
} catch (ignored: IndexOutOfBoundsException) {
|
||||
//do nothing, we don't care, this can happen when everything is working as intended.
|
||||
write(pkt.out, pkt.context)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
} finally {
|
||||
packetsToWrite.clear()
|
||||
e.printStackTrace(pw)
|
||||
SystemLogger.logErr(this::class.java, "Error flushing packet ${pkt.out::class.java}: $sw")
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
queueLock.unlock()
|
||||
|
||||
while (packetsToQueue.isNotEmpty()) {
|
||||
packetsToWrite.add(packetsToQueue.pop())
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
|
|
@ -80,8 +52,7 @@ class PacketWriteQueue : TickListener {
|
|||
val pack = out as? OutgoingPacket<T>
|
||||
val ctx = context as? T
|
||||
if (pack == null || ctx == null) {
|
||||
SystemLogger.logWarn(this::class.java, "Failed packet casting")
|
||||
return
|
||||
throw IllegalStateException("Failed packet casting")
|
||||
}
|
||||
pack.send(ctx)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import core.game.world.GameWorld
|
|||
import core.game.world.repository.Repository
|
||||
import core.game.world.update.UpdateSequence
|
||||
import core.net.packet.PacketProcessor
|
||||
import core.net.packet.PacketWriteQueue
|
||||
import core.tools.colorize
|
||||
import java.lang.Long.max
|
||||
import java.text.SimpleDateFormat
|
||||
|
|
@ -84,6 +85,7 @@ class MajorUpdateWorker {
|
|||
if (!skipPulseUpdate) {
|
||||
GameWorld.Pulser.updateAll()
|
||||
}
|
||||
GameWorld.tickListeners.forEach { it.tick() }
|
||||
|
||||
try {
|
||||
sequence.start()
|
||||
|
|
@ -96,9 +98,10 @@ class MajorUpdateWorker {
|
|||
GameWorld.pulse()
|
||||
//disconnect all players waiting to be disconnected
|
||||
Repository.disconnectionQueue.update()
|
||||
GameWorld.tickListeners.forEach { it.tick() }
|
||||
//tick all manager plugins
|
||||
Managers.tick()
|
||||
|
||||
PacketWriteQueue.flush()
|
||||
}
|
||||
|
||||
fun start() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue