Skip to content

Commit d604bd2

Browse files
committed
grpc-pb: Move JVM exception check to CODEC to avoid performance overhead
Signed-off-by: Johannes Zottele <[email protected]>
1 parent c07edda commit d604bd2

File tree

8 files changed

+81
-70
lines changed

8 files changed

+81
-70
lines changed

grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/pb/WireDecoder.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ public interface WireDecoder : AutoCloseable {
9898
}
9999
}
100100

101+
public expect fun checkForPlatformDecodeException(block: () -> Unit)
102+
101103
/**
102104
* Creates a platform-specific [WireDecoder].
103105
*
@@ -108,4 +110,4 @@ public interface WireDecoder : AutoCloseable {
108110
*
109111
* @param source The buffer containing the encoded wire-format data.
110112
*/
111-
internal expect fun WireDecoder(source: Buffer): WireDecoder
113+
public expect fun WireDecoder(source: Buffer): WireDecoder

grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/pb/WireEncoder.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,6 @@ public interface WireEncoder {
6060
}
6161

6262

63-
internal expect fun WireEncoder(sink: Sink): WireEncoder
63+
public expect fun checkForPlatformEncodeException(block: () -> Unit)
64+
65+
public expect fun WireEncoder(sink: Sink): WireEncoder

grpc/grpc-core/src/commonTest/kotlin/kotlinx/rpc/grpc/pb/WireCodecTest.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,9 @@ class WireCodecTest {
815815
buffer.writeByte(0)
816816

817817
assertFailsWith<ProtobufDecodingException> {
818-
WireDecoder(buffer).readTag()
818+
checkForPlatformDecodeException {
819+
WireDecoder(buffer).readTag()
820+
}
819821
}
820822
}
821823

grpc/grpc-core/src/jvmMain/kotlin/kotlinx/rpc/grpc/pb/WireDecoder.jvm.kt

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,79 +15,79 @@ internal class WireDecoderJvm(source: Buffer) : WireDecoder {
1515
// there is no way to omit coping here
1616
internal val codedInputStream: CodedInputStream = CodedInputStream.newInstance(source.asInputStream())
1717

18-
override fun readTag(): KTag? = checked {
18+
override fun readTag(): KTag? {
1919
val tag = codedInputStream.readTag().toUInt()
2020
if (tag == 0u) {
2121
return null
2222
}
2323
return KTag.from(tag)
2424
}
2525

26-
override fun readBool(): Boolean = checked {
26+
override fun readBool(): Boolean {
2727
return codedInputStream.readBool()
2828
}
2929

30-
override fun readInt32(): Int = checked {
30+
override fun readInt32(): Int {
3131
return codedInputStream.readInt32()
3232
}
3333

34-
override fun readInt64(): Long = checked {
34+
override fun readInt64(): Long {
3535
return codedInputStream.readInt64()
3636
}
3737

38-
override fun readUInt32(): UInt = checked {
38+
override fun readUInt32(): UInt {
3939
// todo check java unsigned types
4040
return codedInputStream.readUInt32().toUInt()
4141
}
4242

43-
override fun readUInt64(): ULong = checked {
43+
override fun readUInt64(): ULong {
4444
// todo check java unsigned types
4545
return codedInputStream.readUInt64().toULong()
4646
}
4747

48-
override fun readSInt32(): Int = checked {
48+
override fun readSInt32(): Int {
4949
return codedInputStream.readSInt32()
5050
}
5151

52-
override fun readSInt64(): Long = checked {
52+
override fun readSInt64(): Long {
5353
return codedInputStream.readSInt64()
5454
}
5555

56-
override fun readFixed32(): UInt = checked {
56+
override fun readFixed32(): UInt {
5757
// todo check java unsigned types
5858
return codedInputStream.readFixed32().toUInt()
5959
}
6060

61-
override fun readFixed64(): ULong = checked {
61+
override fun readFixed64(): ULong {
6262
// todo check java unsigned types
6363
return codedInputStream.readFixed64().toULong()
6464
}
6565

66-
override fun readSFixed32(): Int = checked {
66+
override fun readSFixed32(): Int {
6767
return codedInputStream.readSFixed32()
6868
}
6969

70-
override fun readSFixed64(): Long = checked {
70+
override fun readSFixed64(): Long {
7171
return codedInputStream.readSFixed64()
7272
}
7373

74-
override fun readFloat(): Float = checked {
74+
override fun readFloat(): Float {
7575
return codedInputStream.readFloat()
7676
}
7777

78-
override fun readDouble(): Double = checked {
78+
override fun readDouble(): Double {
7979
return codedInputStream.readDouble()
8080
}
8181

82-
override fun readEnum(): Int = checked {
82+
override fun readEnum(): Int {
8383
return codedInputStream.readEnum()
8484
}
8585

86-
override fun readString(): String = checked {
86+
override fun readString(): String {
8787
return codedInputStream.readStringRequireUtf8()
8888
}
8989

90-
override fun readBytes(): ByteArray = checked {
90+
override fun readBytes(): ByteArray {
9191
return codedInputStream.readByteArray()
9292
}
9393

@@ -114,21 +114,19 @@ internal class WireDecoderJvm(source: Buffer) : WireDecoder {
114114
)
115115
}
116116

117-
internal actual fun WireDecoder(source: Buffer): WireDecoder {
118-
return WireDecoderJvm(source)
119-
}
120117

121-
/**
122-
* Turns a [InvalidProtocolBufferException] into our own [ProtobufDecodingException].
123-
*/
124-
private inline fun <reified T> checked(block: () -> T): T {
118+
public actual fun checkForPlatformDecodeException(block: () -> Unit) {
125119
try {
126120
return block()
127121
} catch (e: InvalidProtocolBufferException) {
128122
throw e.toDecodingException()
129123
}
130124
}
131125

126+
public actual fun WireDecoder(source: Buffer): WireDecoder {
127+
return WireDecoderJvm(source)
128+
}
129+
132130
private fun InvalidProtocolBufferException.toDecodingException(): ProtobufDecodingException {
133131
return ProtobufDecodingException(message ?: "Failed to decode protobuf message.", cause)
134132
}

grpc/grpc-core/src/jvmMain/kotlin/kotlinx/rpc/grpc/pb/WireEncoder.jvm.kt

Lines changed: 33 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,103 +17,103 @@ private class WireEncoderJvm(sink: Sink) : WireEncoder {
1717
codedOutputStream.flush()
1818
}
1919

20-
override fun writeBool(fieldNr: Int, value: Boolean) = checked {
20+
override fun writeBool(fieldNr: Int, value: Boolean) {
2121
codedOutputStream.writeBool(fieldNr, value)
2222
}
2323

24-
override fun writeInt32(fieldNr: Int, value: Int) = checked {
24+
override fun writeInt32(fieldNr: Int, value: Int) {
2525
codedOutputStream.writeInt32(fieldNr, value)
2626
}
2727

28-
override fun writeInt64(fieldNr: Int, value: Long) = checked {
28+
override fun writeInt64(fieldNr: Int, value: Long) {
2929
codedOutputStream.writeInt64(fieldNr, value)
3030
}
3131

32-
override fun writeUInt32(fieldNr: Int, value: UInt) = checked {
32+
override fun writeUInt32(fieldNr: Int, value: UInt) {
3333
// todo check java unsigned types
3434
codedOutputStream.writeUInt32(fieldNr, value.toInt())
3535
}
3636

37-
override fun writeUInt64(fieldNr: Int, value: ULong) = checked {
37+
override fun writeUInt64(fieldNr: Int, value: ULong) {
3838
// todo check java unsigned types
3939
codedOutputStream.writeUInt64(fieldNr, value.toLong())
4040
}
4141

42-
override fun writeSInt32(fieldNr: Int, value: Int) = checked {
42+
override fun writeSInt32(fieldNr: Int, value: Int) {
4343
codedOutputStream.writeSInt32(fieldNr, value)
4444
}
4545

46-
override fun writeSInt64(fieldNr: Int, value: Long) = checked {
46+
override fun writeSInt64(fieldNr: Int, value: Long) {
4747
codedOutputStream.writeSInt64(fieldNr, value)
4848
}
4949

50-
override fun writeFixed32(fieldNr: Int, value: UInt) = checked {
50+
override fun writeFixed32(fieldNr: Int, value: UInt) {
5151
// todo check java unsigned types
5252
codedOutputStream.writeFixed32(fieldNr, value.toInt())
5353
}
5454

55-
override fun writeFixed64(fieldNr: Int, value: ULong) = checked {
55+
override fun writeFixed64(fieldNr: Int, value: ULong) {
5656
// todo check java unsigned types
5757
codedOutputStream.writeFixed64(fieldNr, value.toLong())
5858
}
5959

60-
override fun writeSFixed32(fieldNr: Int, value: Int) = checked {
60+
override fun writeSFixed32(fieldNr: Int, value: Int) {
6161
codedOutputStream.writeSFixed32(fieldNr, value)
6262
}
6363

64-
override fun writeSFixed64(fieldNr: Int, value: Long) = checked {
64+
override fun writeSFixed64(fieldNr: Int, value: Long) {
6565
codedOutputStream.writeSFixed64(fieldNr, value)
6666
}
6767

68-
override fun writeFloat(fieldNr: Int, value: Float) = checked {
68+
override fun writeFloat(fieldNr: Int, value: Float) {
6969
codedOutputStream.writeFloat(fieldNr, value)
7070
}
7171

72-
override fun writeDouble(fieldNr: Int, value: Double) = checked {
72+
override fun writeDouble(fieldNr: Int, value: Double) {
7373
codedOutputStream.writeDouble(fieldNr, value)
7474
}
7575

76-
override fun writeEnum(fieldNr: Int, value: Int) = checked {
76+
override fun writeEnum(fieldNr: Int, value: Int) {
7777
codedOutputStream.writeEnum(fieldNr, value)
7878
}
7979

80-
override fun writeBytes(fieldNr: Int, value: ByteArray) = checked {
80+
override fun writeBytes(fieldNr: Int, value: ByteArray) {
8181
codedOutputStream.writeByteArray(fieldNr, value)
8282
}
8383

84-
override fun writeString(fieldNr: Int, value: String) = checked {
84+
override fun writeString(fieldNr: Int, value: String) {
8585
codedOutputStream.writeString(fieldNr, value)
8686
}
8787

8888
override fun writePackedBool(
8989
fieldNr: Int,
9090
value: List<Boolean>,
9191
fieldSize: Int,
92-
) = checked {
92+
) {
9393
writePackedInternal(fieldNr, value, fieldSize, CodedOutputStream::writeBoolNoTag)
9494
}
9595

9696
override fun writePackedInt32(
9797
fieldNr: Int,
9898
value: List<Int>,
9999
fieldSize: Int,
100-
) = checked {
100+
) {
101101
writePackedInternal(fieldNr, value, fieldSize, CodedOutputStream::writeInt32NoTag)
102102
}
103103

104104
override fun writePackedInt64(
105105
fieldNr: Int,
106106
value: List<Long>,
107107
fieldSize: Int,
108-
) = checked {
108+
) {
109109
writePackedInternal(fieldNr, value, fieldSize, CodedOutputStream::writeInt64NoTag)
110110
}
111111

112112
override fun writePackedUInt32(
113113
fieldNr: Int,
114114
value: List<UInt>,
115115
fieldSize: Int,
116-
) = checked {
116+
) {
117117
writePackedInternal(fieldNr, value, fieldSize) { codedOutputStream, v ->
118118
codedOutputStream.writeUInt32NoTag(v.toInt())
119119
}
@@ -123,7 +123,7 @@ private class WireEncoderJvm(sink: Sink) : WireEncoder {
123123
fieldNr: Int,
124124
value: List<ULong>,
125125
fieldSize: Int,
126-
) = checked {
126+
) {
127127
writePackedInternal(fieldNr, value, fieldSize) { codedOutputStream, v ->
128128
codedOutputStream.writeUInt64NoTag(v.toLong())
129129
}
@@ -133,43 +133,43 @@ private class WireEncoderJvm(sink: Sink) : WireEncoder {
133133
fieldNr: Int,
134134
value: List<Int>,
135135
fieldSize: Int,
136-
) = checked {
136+
) {
137137
writePackedInternal(fieldNr, value, fieldSize, CodedOutputStream::writeSInt32NoTag)
138138
}
139139

140140
override fun writePackedSInt64(
141141
fieldNr: Int,
142142
value: List<Long>,
143143
fieldSize: Int,
144-
) = checked {
144+
) {
145145
writePackedInternal(fieldNr, value, fieldSize, CodedOutputStream::writeSInt64NoTag)
146146
}
147147

148-
override fun writePackedFixed32(fieldNr: Int, value: List<UInt>) = checked {
148+
override fun writePackedFixed32(fieldNr: Int, value: List<UInt>) {
149149
writePackedInternal(fieldNr, value, value.size * UInt.SIZE_BYTES) { codedOutputStream, v ->
150150
codedOutputStream.writeFixed32NoTag(v.toInt())
151151
}
152152
}
153153

154-
override fun writePackedFixed64(fieldNr: Int, value: List<ULong>) = checked {
154+
override fun writePackedFixed64(fieldNr: Int, value: List<ULong>) {
155155
writePackedInternal(fieldNr, value, value.size * ULong.SIZE_BYTES) { codedOutputStream, v ->
156156
codedOutputStream.writeFixed64NoTag(v.toLong())
157157
}
158158
}
159159

160-
override fun writePackedSFixed32(fieldNr: Int, value: List<Int>) = checked {
160+
override fun writePackedSFixed32(fieldNr: Int, value: List<Int>) {
161161
writePackedInternal(fieldNr, value, value.size * Int.SIZE_BYTES, CodedOutputStream::writeSFixed32NoTag)
162162
}
163163

164-
override fun writePackedSFixed64(fieldNr: Int, value: List<Long>) = checked {
164+
override fun writePackedSFixed64(fieldNr: Int, value: List<Long>) {
165165
writePackedInternal(fieldNr, value, value.size * Long.SIZE_BYTES, CodedOutputStream::writeSFixed64NoTag)
166166
}
167167

168-
override fun writePackedFloat(fieldNr: Int, value: List<Float>) = checked {
168+
override fun writePackedFloat(fieldNr: Int, value: List<Float>) {
169169
writePackedInternal(fieldNr, value, value.size * Float.SIZE_BYTES, CodedOutputStream::writeFloatNoTag)
170170
}
171171

172-
override fun writePackedDouble(fieldNr: Int, value: List<Double>) = checked {
172+
override fun writePackedDouble(fieldNr: Int, value: List<Double>) {
173173
writePackedInternal(fieldNr, value, value.size * Double.SIZE_BYTES, CodedOutputStream::writeDoubleNoTag)
174174
}
175175

@@ -188,7 +188,7 @@ private class WireEncoderJvm(sink: Sink) : WireEncoder {
188188
value: List<T>,
189189
fieldSize: Int,
190190
crossinline writer: (CodedOutputStream, T) -> Unit,
191-
) = checked {
191+
) {
192192
codedOutputStream.writeTag(fieldNr, WireType.LENGTH_DELIMITED.ordinal)
193193
// write the field size of the packed field
194194
codedOutputStream.writeInt32NoTag(fieldSize)
@@ -198,17 +198,14 @@ private class WireEncoderJvm(sink: Sink) : WireEncoder {
198198
}
199199
}
200200

201-
internal actual fun WireEncoder(sink: Sink): WireEncoder {
201+
public actual fun WireEncoder(sink: Sink): WireEncoder {
202202
return WireEncoderJvm(sink)
203203
}
204204

205-
/**
206-
* Wraps a [kotlinx.io.IOException] in our own [kotlinx.rpc.grpc.ProtobufEncodingException].
207-
*/
208-
private inline fun checked(crossinline block: () -> Unit) {
205+
public actual fun checkForPlatformEncodeException(block: () -> Unit) {
209206
try {
210207
return block()
211208
} catch (e: IOException) {
212209
throw ProtobufEncodingException("Failed to encode protobuf message.", e)
213210
}
214-
}
211+
}

grpc/grpc-core/src/nativeMain/kotlin/kotlinx/rpc/grpc/pb/WireDecoder.native.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,4 +301,8 @@ internal class WireDecoderNative(private val source: Buffer) : WireDecoder {
301301
}
302302
}
303303

304-
internal actual fun WireDecoder(source: Buffer): WireDecoder = WireDecoderNative(source)
304+
public actual fun WireDecoder(source: Buffer): WireDecoder = WireDecoderNative(source)
305+
306+
public actual fun checkForPlatformDecodeException(block: () -> Unit) {
307+
block()
308+
}

0 commit comments

Comments
 (0)