Moved Kryoextra, moved Aeron IO, fixed generics with serialization
This commit is contained in:
parent
1b796971d3
commit
d9ab3f7247
|
@ -271,8 +271,6 @@ class RemoteObjectStorage(val logger: KLogger) {
|
|||
* @return the object registered with the specified ID.
|
||||
*/
|
||||
operator fun get(objectId: Int): Any? {
|
||||
validate(objectId)
|
||||
|
||||
return objectMap[objectId]
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package dorkbox.network.rmi
|
||||
|
||||
import com.conversantmedia.util.concurrent.MultithreadConcurrentQueue
|
||||
import dorkbox.network.rmi.messages.MethodResponse
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
|
@ -30,8 +29,8 @@ internal data class RmiWaiter(val id: Int) {
|
|||
* this will replace the waiter if it was cancelled (waiters are not valid if cancelled)
|
||||
*/
|
||||
fun prep() {
|
||||
@Suppress("EXPERIMENTAL_API_USAGE")
|
||||
if (channel.isClosedForReceive && channel.isClosedForSend) {
|
||||
println("renew waiter")
|
||||
channel = Channel(0)
|
||||
}
|
||||
}
|
||||
|
@ -74,17 +73,20 @@ internal class RmiResponseStorage(private val actionDispatch: CoroutineScope) {
|
|||
// Response ID's are for ALL in-flight RMI on the network stack. instead of limited to (originally) 64, we are now limited to 65,535
|
||||
// these are just looped around in a ring buffer.
|
||||
// These are stored here as int, however these are REALLY shorts and are int-packed when transferring data on the wire
|
||||
// 32,000 IN FLIGHT RMI method invocations is PLENTY
|
||||
private val maxValuesInCache = Short.MAX_VALUE.toInt()
|
||||
|
||||
private val rmiWaiterCache = MultithreadConcurrentQueue<RmiWaiter>(maxValuesInCache)
|
||||
// 64,000 IN FLIGHT RMI method invocations is PLENTY
|
||||
private val maxValuesInCache = (Short.MAX_VALUE.toInt() * 2) - 1 // -1 because 0 is reserved
|
||||
private val rmiWaiterCache = Channel<RmiWaiter>(maxValuesInCache)
|
||||
|
||||
private val pendingLock = ReentrantReadWriteLock()
|
||||
private val pending = Int2NullableObjectHashMap<Any>(32, Hashing.DEFAULT_LOAD_FACTOR, true)
|
||||
|
||||
|
||||
init {
|
||||
// create a shuffled list of ID's. This operation is ONLY performed ONE TIME per endpoint!
|
||||
val ids = IntArrayList(maxValuesInCache, Integer.MIN_VALUE)
|
||||
for (id in Short.MIN_VALUE..-1) {
|
||||
ids.addInt(id)
|
||||
}
|
||||
// ZERO is special, and is never added!
|
||||
for (id in 1..Short.MAX_VALUE) {
|
||||
ids.addInt(id)
|
||||
|
@ -114,15 +116,15 @@ internal class RmiResponseStorage(private val actionDispatch: CoroutineScope) {
|
|||
previous.doNotify()
|
||||
|
||||
// since this was the FIRST one to trigger, return it to the cache.
|
||||
rmiWaiterCache.offer(previous)
|
||||
rmiWaiterCache.send(previous)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the RmiWaiter (id + waiter)
|
||||
*/
|
||||
internal fun prep(rmiObjectId: Int): RmiWaiter {
|
||||
val responseRmi = rmiWaiterCache.poll()
|
||||
internal suspend fun prep(rmiObjectId: Int): RmiWaiter {
|
||||
val responseRmi = rmiWaiterCache.receive()
|
||||
|
||||
// this will replace the waiter if it was cancelled (waiters are not valid if cancelled)
|
||||
responseRmi.prep()
|
||||
|
@ -175,7 +177,7 @@ internal class RmiResponseStorage(private val actionDispatch: CoroutineScope) {
|
|||
val resultOrWaiter = pendingLock.write { pending.remove(pendingId) }
|
||||
if (resultOrWaiter is RmiWaiter) {
|
||||
// since this was the FIRST one to trigger, return it to the cache.
|
||||
rmiWaiterCache.offer(resultOrWaiter)
|
||||
rmiWaiterCache.send(resultOrWaiter)
|
||||
return TIMEOUT_EXCEPTION
|
||||
}
|
||||
|
||||
|
@ -183,7 +185,7 @@ internal class RmiResponseStorage(private val actionDispatch: CoroutineScope) {
|
|||
}
|
||||
|
||||
fun close() {
|
||||
rmiWaiterCache.clear()
|
||||
rmiWaiterCache.close()
|
||||
pendingLock.write { pending.clear() }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,8 +39,8 @@ import com.esotericsoftware.kryo.KryoException
|
|||
import com.esotericsoftware.kryo.Serializer
|
||||
import com.esotericsoftware.kryo.io.Input
|
||||
import com.esotericsoftware.kryo.io.Output
|
||||
import dorkbox.network.connection.KryoExtra
|
||||
import dorkbox.network.rmi.RmiUtils
|
||||
import dorkbox.network.serialization.KryoExtra
|
||||
import java.lang.reflect.Method
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,8 +19,8 @@ import com.esotericsoftware.kryo.Kryo
|
|||
import com.esotericsoftware.kryo.Serializer
|
||||
import com.esotericsoftware.kryo.io.Input
|
||||
import com.esotericsoftware.kryo.io.Output
|
||||
import dorkbox.network.connection.KryoExtra
|
||||
import dorkbox.network.rmi.RmiClient
|
||||
import dorkbox.network.serialization.KryoExtra
|
||||
import java.lang.reflect.Proxy
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package dorkbox.network.pipeline;
|
||||
package dorkbox.network.serialization;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
|
@ -32,7 +32,7 @@
|
|||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package dorkbox.network.pipeline;
|
||||
package dorkbox.network.serialization;
|
||||
|
||||
import java.io.DataOutput;
|
||||
import java.io.OutputStream;
|
|
@ -16,8 +16,7 @@
|
|||
package dorkbox.network.serialization
|
||||
|
||||
import com.esotericsoftware.kryo.Serializer
|
||||
import dorkbox.network.connection.KryoExtra
|
||||
import org.slf4j.Logger
|
||||
import mu.KLogger
|
||||
|
||||
internal open class ClassRegistration(var clazz: Class<*>) {
|
||||
var id = 0
|
||||
|
@ -28,8 +27,10 @@ internal open class ClassRegistration(var clazz: Class<*>) {
|
|||
id = registration.id
|
||||
}
|
||||
|
||||
open fun log(logger: Logger) {
|
||||
logger.trace("Registered {} -> {}", id, clazz.name)
|
||||
open fun log(logger: KLogger) {
|
||||
logger.trace {
|
||||
"Registered $id -> ${clazz.name}"
|
||||
}
|
||||
}
|
||||
|
||||
fun getInfoArray(): Array<Any> {
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
package dorkbox.network.serialization
|
||||
|
||||
import com.esotericsoftware.kryo.Serializer
|
||||
import dorkbox.network.connection.KryoExtra
|
||||
import org.slf4j.Logger
|
||||
import mu.KLogger
|
||||
|
||||
internal class ClassRegistration0(clazz: Class<*>, serializer: Serializer<*>) : ClassRegistration(clazz) {
|
||||
init {
|
||||
|
@ -28,7 +27,9 @@ internal class ClassRegistration0(clazz: Class<*>, serializer: Serializer<*>) :
|
|||
id = kryo.register(clazz, serializer).id
|
||||
}
|
||||
|
||||
override fun log(logger: Logger) {
|
||||
logger.trace("Registered {} -> {} using {}", id, clazz.name, serializer?.javaClass?.name)
|
||||
override fun log(logger: KLogger) {
|
||||
logger.trace {
|
||||
"Registered $id -> ${clazz.name} using ${serializer?.javaClass?.name}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
*/
|
||||
package dorkbox.network.serialization
|
||||
|
||||
import dorkbox.network.connection.KryoExtra
|
||||
import org.slf4j.Logger
|
||||
import mu.KLogger
|
||||
|
||||
internal class ClassRegistration1(clazz: Class<*>, id: Int) : ClassRegistration(clazz) {
|
||||
init {
|
||||
|
@ -27,7 +26,9 @@ internal class ClassRegistration1(clazz: Class<*>, id: Int) : ClassRegistration(
|
|||
kryo.register(clazz, id)
|
||||
}
|
||||
|
||||
override fun log(logger: Logger) {
|
||||
logger.trace("Registered {} -> (specified) {}", id, clazz.name)
|
||||
override fun log(logger: KLogger) {
|
||||
logger.trace {
|
||||
"Registered $id -> (specified) ${clazz.name}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
package dorkbox.network.serialization
|
||||
|
||||
import com.esotericsoftware.kryo.Serializer
|
||||
import dorkbox.network.connection.KryoExtra
|
||||
import org.slf4j.Logger
|
||||
import mu.KLogger
|
||||
|
||||
internal class ClassRegistration2(clazz: Class<*>, serializer: Serializer<*>, id: Int) : ClassRegistration(clazz) {
|
||||
init {
|
||||
|
@ -29,7 +28,9 @@ internal class ClassRegistration2(clazz: Class<*>, serializer: Serializer<*>, id
|
|||
kryo.register(clazz, serializer, id)
|
||||
}
|
||||
|
||||
override fun log(logger: Logger) {
|
||||
logger.trace("Registered {} -> (specified) {} using {}", id, clazz.name, serializer?.javaClass?.name)
|
||||
override fun log(logger: KLogger) {
|
||||
logger.trace {
|
||||
"Registered $id -> (specified) ${clazz.name} using ${serializer?.javaClass?.name}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,9 +15,8 @@
|
|||
*/
|
||||
package dorkbox.network.serialization
|
||||
|
||||
import dorkbox.network.connection.KryoExtra
|
||||
import dorkbox.network.rmi.messages.ObjectResponseSerializer
|
||||
import org.slf4j.Logger
|
||||
import mu.KLogger
|
||||
|
||||
internal class ClassRegistrationIfaceAndImpl(ifaceClass: Class<*>, val implClass: Class<*>, objectResponseSerializer: ObjectResponseSerializer) : ClassRegistration(ifaceClass) {
|
||||
|
||||
|
@ -29,7 +28,9 @@ internal class ClassRegistrationIfaceAndImpl(ifaceClass: Class<*>, val implClass
|
|||
id = kryo.register(clazz, serializer).id
|
||||
}
|
||||
|
||||
override fun log(logger: Logger) {
|
||||
logger.trace("Registered {} -> (RMI) {}", id, implClass.name)
|
||||
override fun log(logger: KLogger) {
|
||||
logger.trace {
|
||||
"Registered $id -> (RMI) ${implClass.name}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
package dorkbox.network.serialization;
|
||||
|
||||
/**
|
||||
* Signals the remote end that certain things need to happen
|
||||
*/
|
||||
public
|
||||
class ControlMessage {
|
||||
public static final byte INVALID_STATUS = 0x0;
|
||||
public static final byte CONNECTING = 0x2;
|
||||
public static final byte CONNECTED = 0x3;
|
||||
|
||||
public static final byte DISCONNECT = 0x7F; // max signed byte value, 127
|
||||
|
||||
|
||||
public byte command = INVALID_STATUS;
|
||||
public byte payload = INVALID_STATUS;
|
||||
|
||||
public ControlMessage() {
|
||||
}
|
||||
}
|
|
@ -13,13 +13,12 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package dorkbox.network.connection
|
||||
package dorkbox.network.serialization
|
||||
|
||||
import com.esotericsoftware.kryo.Kryo
|
||||
import com.esotericsoftware.kryo.io.Input
|
||||
import com.esotericsoftware.kryo.io.Output
|
||||
import dorkbox.network.pipeline.AeronInput
|
||||
import dorkbox.network.pipeline.AeronOutput
|
||||
import dorkbox.network.connection.Connection
|
||||
import dorkbox.network.rmi.CachedMethod
|
||||
import dorkbox.os.OS
|
||||
import dorkbox.util.Sys
|
||||
|
@ -29,7 +28,6 @@ import org.agrona.DirectBuffer
|
|||
import org.agrona.collections.Int2ObjectHashMap
|
||||
import org.slf4j.Logger
|
||||
import java.io.IOException
|
||||
import javax.crypto.Cipher
|
||||
|
||||
/**
|
||||
* Nothing in this class is thread safe
|
||||
|
@ -50,7 +48,7 @@ class KryoExtra(private val methodCache: Int2ObjectHashMap<Array<CachedMethod>>)
|
|||
lateinit var connection: Connection
|
||||
|
||||
// private val secureRandom = SecureRandom()
|
||||
private var cipher: Cipher? = null
|
||||
// private var cipher: Cipher? = null
|
||||
private val compressor = factory.fastCompressor()
|
||||
private val decompressor = factory.fastDecompressor()
|
||||
|
||||
|
@ -69,13 +67,13 @@ class KryoExtra(private val methodCache: Int2ObjectHashMap<Array<CachedMethod>>)
|
|||
private const val IV_LENGTH_BYTE = 12
|
||||
}
|
||||
|
||||
init {
|
||||
cipher = try {
|
||||
Cipher.getInstance(ALGORITHM)
|
||||
} catch (e: Exception) {
|
||||
throw IllegalStateException("could not get cipher instance", e)
|
||||
}
|
||||
}
|
||||
// init {
|
||||
// cipher = try {
|
||||
// Cipher.getInstance(ALGORITHM)
|
||||
// } catch (e: Exception) {
|
||||
// throw IllegalStateException("could not get cipher instance", e)
|
||||
// }
|
||||
// }
|
||||
|
||||
fun getMethods(classId: Int): Array<CachedMethod> {
|
||||
return methodCache[classId]
|
|
@ -16,7 +16,6 @@
|
|||
package dorkbox.network.serialization
|
||||
|
||||
import com.esotericsoftware.kryo.Serializer
|
||||
import dorkbox.network.connection.KryoExtra
|
||||
import dorkbox.network.rmi.CachedMethod
|
||||
import dorkbox.util.serialization.SerializationManager
|
||||
import org.agrona.DirectBuffer
|
||||
|
@ -81,17 +80,17 @@ interface NetworkSerializationManager : SerializationManager<DirectBuffer> {
|
|||
/**
|
||||
* @return takes a kryo instance from the pool.
|
||||
*/
|
||||
fun takeKryo(): KryoExtra
|
||||
suspend fun takeKryo(): KryoExtra
|
||||
|
||||
/**
|
||||
* Returns a kryo instance to the pool.
|
||||
*/
|
||||
fun returnKryo(kryo: KryoExtra)
|
||||
suspend fun returnKryo(kryo: KryoExtra)
|
||||
|
||||
/**
|
||||
* @return true if the remote kryo registration are the same as our own
|
||||
*/
|
||||
fun verifyKryoRegistration(clientBytes: ByteArray): Boolean
|
||||
suspend fun verifyKryoRegistration(clientBytes: ByteArray): Boolean
|
||||
|
||||
/**
|
||||
* @return the details of all registration IDs -> Class name used by kryo
|
||||
|
@ -145,7 +144,7 @@ interface NetworkSerializationManager : SerializationManager<DirectBuffer> {
|
|||
/**
|
||||
* Called when initialization is complete. This is to prevent (and recognize) out-of-order class/serializer registration.
|
||||
*/
|
||||
fun finishInit(endPointClass: Class<*>)
|
||||
suspend fun finishInit(endPointClass: Class<*>)
|
||||
|
||||
/**
|
||||
* @return true if our initialization is complete. Some registrations (in the property store, for example) always register for client
|
||||
|
|
|
@ -23,25 +23,31 @@ import com.esotericsoftware.kryo.io.Input
|
|||
import com.esotericsoftware.kryo.io.Output
|
||||
import com.esotericsoftware.kryo.util.DefaultInstantiatorStrategy
|
||||
import com.esotericsoftware.kryo.util.IdentityMap
|
||||
import dorkbox.network.connection.KryoExtra
|
||||
import dorkbox.network.connection.ping.PingMessage
|
||||
import dorkbox.network.handshake.Message
|
||||
import dorkbox.network.pipeline.AeronInput
|
||||
import dorkbox.network.pipeline.AeronOutput
|
||||
import dorkbox.network.handshake.HandshakeMessage
|
||||
import dorkbox.network.rmi.CachedMethod
|
||||
import dorkbox.network.rmi.RmiUtils
|
||||
import dorkbox.network.rmi.messages.*
|
||||
import dorkbox.objectPool.ObjectPool
|
||||
import dorkbox.objectPool.PoolableObject
|
||||
import dorkbox.network.rmi.messages.ConnectionObjectCreateRequest
|
||||
import dorkbox.network.rmi.messages.ConnectionObjectCreateResponse
|
||||
import dorkbox.network.rmi.messages.GlobalObjectCreateRequest
|
||||
import dorkbox.network.rmi.messages.GlobalObjectCreateResponse
|
||||
import dorkbox.network.rmi.messages.MethodRequest
|
||||
import dorkbox.network.rmi.messages.MethodRequestSerializer
|
||||
import dorkbox.network.rmi.messages.MethodResponse
|
||||
import dorkbox.network.rmi.messages.MethodResponseSerializer
|
||||
import dorkbox.network.rmi.messages.ObjectResponseSerializer
|
||||
import dorkbox.network.rmi.messages.RmiClientRequestSerializer
|
||||
import dorkbox.os.OS
|
||||
import dorkbox.util.serialization.SerializationDefaults
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import mu.KLogger
|
||||
import mu.KotlinLogging
|
||||
import org.agrona.DirectBuffer
|
||||
import org.agrona.MutableDirectBuffer
|
||||
import org.agrona.collections.Int2ObjectHashMap
|
||||
import org.objenesis.instantiator.ObjectInstantiator
|
||||
import org.objenesis.strategy.StdInstantiatorStrategy
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.IOException
|
||||
import java.lang.reflect.Constructor
|
||||
import java.lang.reflect.InvocationHandler
|
||||
|
@ -66,8 +72,8 @@ import java.lang.reflect.InvocationHandler
|
|||
* an object's type. Default is [ReflectionSerializerFactory] with [FieldSerializer]. @see
|
||||
* Kryo#newDefaultSerializer(Class)
|
||||
*/
|
||||
class Serialization(references: Boolean,
|
||||
factory: SerializerFactory<*>?) : NetworkSerializationManager {
|
||||
class Serialization(private val references: Boolean,
|
||||
private val factory: SerializerFactory<*>?) : NetworkSerializationManager {
|
||||
|
||||
|
||||
companion object {
|
||||
|
@ -86,7 +92,6 @@ class Serialization(references: Boolean,
|
|||
fun DEFAULT(references: Boolean = true, factory: SerializerFactory<*>? = null): Serialization {
|
||||
val serialization = Serialization(references, factory)
|
||||
|
||||
serialization.register(ControlMessage::class.java)
|
||||
serialization.register(PingMessage::class.java) // TODO this is built into aeron!??!?!?!
|
||||
|
||||
// TODO: this is for diffie hellmen handshake stuff!
|
||||
|
@ -95,16 +100,16 @@ class Serialization(references: Boolean,
|
|||
// TODO: fix kryo to work the way we want, so we can register interfaces + serializers with kryo
|
||||
// serialization.register(XECPublicKey::class.java, XECPublicKeySerializer())
|
||||
// serialization.register(XECPrivateKey::class.java, XECPrivateKeySerializer())
|
||||
serialization.register(Message::class.java) // must use full package name!
|
||||
// serialization.register(Message::class.java) // must use full package name!
|
||||
|
||||
return serialization
|
||||
}
|
||||
}
|
||||
|
||||
private lateinit var logger: Logger
|
||||
private lateinit var logger: KLogger
|
||||
|
||||
private var initialized = false
|
||||
private val kryoPool: ObjectPool<KryoExtra>
|
||||
private val kryoPool: Channel<KryoExtra>
|
||||
lateinit var classResolver: ClassResolver
|
||||
|
||||
// used by operations performed during kryo initialization, which are by default package access (since it's an anon-inner class)
|
||||
|
@ -137,12 +142,14 @@ class Serialization(references: Boolean,
|
|||
// reflectASM doesn't work on android
|
||||
private val useAsm = !OS.isAndroid()
|
||||
|
||||
private val KRYO_COUNT = 32
|
||||
init {
|
||||
kryoPool = ObjectPool.NonBlockingSoftReference(object : PoolableObject<KryoExtra>() {
|
||||
override fun create(): KryoExtra {
|
||||
synchronized(this@Serialization) {
|
||||
// reasonable size of available kryo's before coroutines are suspended during read/write
|
||||
kryoPool = Channel(KRYO_COUNT)
|
||||
}
|
||||
|
||||
// we HAVE to pre-allocate the KRYOs
|
||||
@Synchronized
|
||||
private fun initKryo(): KryoExtra {
|
||||
val kryo = KryoExtra(methodCache)
|
||||
|
||||
kryo.instantiatorStrategy = instantiatorStrategy
|
||||
|
@ -152,6 +159,7 @@ class Serialization(references: Boolean,
|
|||
SerializationDefaults.register(kryo)
|
||||
|
||||
// RMI stuff!
|
||||
kryo.register(HandshakeMessage::class.java)
|
||||
kryo.register(GlobalObjectCreateRequest::class.java)
|
||||
kryo.register(GlobalObjectCreateResponse::class.java)
|
||||
|
||||
|
@ -175,9 +183,7 @@ class Serialization(references: Boolean,
|
|||
|
||||
return kryo
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
@ -321,16 +327,15 @@ class Serialization(references: Boolean,
|
|||
* is already in use by a different type, an exception is thrown.
|
||||
*/
|
||||
@Synchronized
|
||||
override fun finishInit(endPointClass: Class<*>) {
|
||||
val name = endPointClass.simpleName
|
||||
|
||||
this.logger = LoggerFactory.getLogger("$name.SERIAL")
|
||||
override suspend fun finishInit(endPointClass: Class<*>) {
|
||||
this.logger = KotlinLogging.logger(endPointClass.simpleName)
|
||||
|
||||
initialized = true
|
||||
|
||||
// initialize the kryo pool with at least 1 kryo instance. This ALSO makes sure that all of our class registration is done
|
||||
// correctly and (if not) we are are notified on the initial thread (instead of on the network update thread)
|
||||
val kryo = kryoPool.take()
|
||||
val kryo = takeKryo()
|
||||
|
||||
// save off the class-resolver, so we can lookup the class <-> id relationships
|
||||
classResolver = kryo.classResolver
|
||||
|
||||
|
@ -413,7 +418,7 @@ class Serialization(references: Boolean,
|
|||
output.toBytes().copyInto(savedRegistrationDetails, 0, 0, length)
|
||||
output.close()
|
||||
} finally {
|
||||
kryoPool.put(kryo)
|
||||
returnKryo(kryo)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -435,7 +440,7 @@ class Serialization(references: Boolean,
|
|||
*
|
||||
* @return true if kryo registration is required for all classes sent over the wire
|
||||
*/
|
||||
override fun verifyKryoRegistration(clientBytes: ByteArray): Boolean {
|
||||
override suspend fun verifyKryoRegistration(clientBytes: ByteArray): Boolean {
|
||||
// verify the registration IDs if necessary with our own. The CLIENT does not verify anything, only the server!
|
||||
val kryoRegistrationDetails = savedRegistrationDetails
|
||||
val equals = kryoRegistrationDetails.contentEquals(clientBytes)
|
||||
|
@ -505,7 +510,9 @@ class Serialization(references: Boolean,
|
|||
// JUST MAYBE this is a serializer for RMI. The client doesn't have to register for RMI stuff
|
||||
|
||||
if (serializerServer == objectResponseSerializer::class.java.name && serializerClient.isEmpty()) {
|
||||
// this is for RMI!
|
||||
// this is for SERVER RMI!
|
||||
} else if (serializerClient == objectResponseSerializer::class.java.name && serializerServer.isEmpty()) {
|
||||
// this is for CLIENT RMI!
|
||||
} else {
|
||||
success = false
|
||||
logger.error("Registration {} Client -> {} ({})", idClient, nameClient, serializerClient)
|
||||
|
@ -543,15 +550,16 @@ class Serialization(references: Boolean,
|
|||
/**
|
||||
* @return takes a kryo instance from the pool.
|
||||
*/
|
||||
override fun takeKryo(): KryoExtra {
|
||||
return kryoPool.take()
|
||||
override suspend fun takeKryo(): KryoExtra {
|
||||
// ALWAYS get as many as needed. Recycle them to prevent too many getting created
|
||||
return kryoPool.poll() ?: initKryo()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a kryo instance to the pool.
|
||||
* Returns a kryo instance to the pool for use later on
|
||||
*/
|
||||
override fun returnKryo(kryo: KryoExtra) {
|
||||
kryoPool.put(kryo)
|
||||
override suspend fun returnKryo(kryo: KryoExtra) {
|
||||
kryoPool.send(kryo)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -638,50 +646,52 @@ class Serialization(references: Boolean,
|
|||
}
|
||||
|
||||
/**
|
||||
* # BLOCKING
|
||||
*
|
||||
* Waits until a kryo is available to write, using CAS operations to prevent having to synchronize.
|
||||
*
|
||||
*
|
||||
* No crypto and no sequence number
|
||||
*
|
||||
*
|
||||
* There is a small speed penalty if there were no kryo's available to use.
|
||||
*/
|
||||
@Throws(IOException::class)
|
||||
override fun write(buffer: DirectBuffer, message: Any) {
|
||||
val kryo = kryoPool.take()
|
||||
runBlocking {
|
||||
val kryo = takeKryo()
|
||||
try {
|
||||
val output = AeronOutput(buffer as MutableDirectBuffer)
|
||||
kryo.writeClassAndObject(output, message)
|
||||
} finally {
|
||||
kryoPool.put(kryo)
|
||||
returnKryo(kryo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* # BLOCKING
|
||||
*
|
||||
* Reads an object from the buffer.
|
||||
*
|
||||
*
|
||||
* No crypto and no sequence number
|
||||
*
|
||||
* @param length should ALWAYS be the length of the expected object!
|
||||
*/
|
||||
@Throws(IOException::class)
|
||||
override fun read(buffer: DirectBuffer, length: Int): Any? {
|
||||
val kryo = kryoPool.take()
|
||||
return try {
|
||||
return runBlocking {
|
||||
val kryo = takeKryo()
|
||||
try {
|
||||
val input = AeronInput(buffer)
|
||||
kryo.readClassAndObject(input)
|
||||
} finally {
|
||||
kryoPool.put(kryo)
|
||||
returnKryo(kryo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* # BLOCKING
|
||||
*
|
||||
* Writes the class and object using an available kryo instance
|
||||
*/
|
||||
@Throws(IOException::class)
|
||||
override fun writeFullClassAndObject(output: Output, value: Any) {
|
||||
val kryo = kryoPool.take()
|
||||
runBlocking {
|
||||
val kryo = takeKryo()
|
||||
var prev = false
|
||||
try {
|
||||
prev = kryo.isRegistrationRequired
|
||||
|
@ -693,18 +703,22 @@ class Serialization(references: Boolean,
|
|||
throw IOException(msg, ex)
|
||||
} finally {
|
||||
kryo.isRegistrationRequired = prev
|
||||
kryoPool.put(kryo)
|
||||
returnKryo(kryo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* # BLOCKING
|
||||
*
|
||||
* Returns a class read from the input
|
||||
*/
|
||||
@Throws(IOException::class)
|
||||
override fun readFullClassAndObject(input: Input): Any {
|
||||
val kryo = kryoPool.take()
|
||||
return runBlocking {
|
||||
val kryo = takeKryo()
|
||||
var prev = false
|
||||
return try {
|
||||
try {
|
||||
prev = kryo.isRegistrationRequired
|
||||
kryo.isRegistrationRequired = false
|
||||
kryo.readClassAndObject(input)
|
||||
|
@ -714,7 +728,8 @@ class Serialization(references: Boolean,
|
|||
throw IOException(msg, ex)
|
||||
} finally {
|
||||
kryo.isRegistrationRequired = prev
|
||||
kryoPool.put(kryo)
|
||||
returnKryo(kryo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user