mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-04 23:39:07 +07:00
IJPL-159270 IJent: don't send huge chunks over gRPC
* There's a hard limit for an *incoming* message in gRPC-Java. The new code doesn't send requests that lead to huge responses. * Requests for huge data chunks lead to bigger memory consumption on the remote side. GitOrigin-RevId: 376b2c20a1ea3a7ce65527ba4b7d979f9bc245af
This commit is contained in:
committed by
intellij-monorepo-bot
parent
9278a9eafa
commit
d18bb6ac3a
@@ -28,6 +28,9 @@ sealed interface IjentTunnelsApi {
|
||||
* The connection exists as a pair of channels [Connection.channelToServer] and [Connection.channelFromServer],
|
||||
* which allow communicating to a remote server from the IDE side.
|
||||
*
|
||||
* Packets sent to the channel and received from the channel may be split and/or concatenated.
|
||||
* The packets may be split only if their size exceeds [com.intellij.platform.ijent.spi.RECOMMENDED_MAX_PACKET_SIZE].
|
||||
*
|
||||
* If the connection gets closed from the server, then the channels also get closed in the sense of [SendChannel.close].
|
||||
*
|
||||
* If an exception happens during sending, then [Connection.channelFromServer] gets closed exceptionally with [RemoteNetworkException].
|
||||
@@ -178,9 +181,12 @@ operator fun Connection.component2(): ReceiveChannel<ByteBuffer> = channelFromSe
|
||||
|
||||
interface IjentTunnelsPosixApi : IjentTunnelsApi {
|
||||
/**
|
||||
* Creates a remote UNIX socket forwarding, i.e. IJent listens waits for a connection on the remote machine, and when the connection
|
||||
* Creates a remote UNIX socket forwarding. IJent listens for a connection on the remote machine, and when the connection
|
||||
* is accepted, the IDE communicates to the remote client via a pair of Kotlin channels.
|
||||
*
|
||||
* Packets sent to the channel and received from the channel may be split and/or concatenated.
|
||||
* The packets may be split only if their size exceeds [com.intellij.platform.ijent.spi.RECOMMENDED_MAX_PACKET_SIZE].
|
||||
*
|
||||
* The call accepts only one connection. If multiple connections should be accepted, the function is supposed to be called in a loop:
|
||||
* ```kotlin
|
||||
* val ijent: IjentApi = ijentApiFactory()
|
||||
|
||||
@@ -268,6 +268,8 @@ sealed interface IjentOpenedFile {
|
||||
* Note, that [ReadResult.Bytes] can be `0` if [buf] cannot accept new data.
|
||||
*
|
||||
* This operation modifies the file's cursor, i.e. [tell] may show different results before and after this function is invoked.
|
||||
*
|
||||
* It reads not more than [com.intellij.platform.ijent.spi.RECOMMENDED_MAX_PACKET_SIZE].
|
||||
*/
|
||||
suspend fun read(buf: ByteBuffer): IjentFsResult<ReadResult, ReadError>
|
||||
|
||||
@@ -275,6 +277,8 @@ sealed interface IjentOpenedFile {
|
||||
* Reads data from the position [offset] of the file.
|
||||
*
|
||||
* This operation does not modify the file's cursor, i.e. [tell] will show the same result before and after this function is invoked.
|
||||
*
|
||||
* It reads not more than [com.intellij.platform.ijent.spi.RECOMMENDED_MAX_PACKET_SIZE].
|
||||
*/
|
||||
suspend fun read(buf: ByteBuffer, offset: Long) : IjentFsResult<ReadResult, ReadError>
|
||||
|
||||
@@ -293,10 +297,20 @@ sealed interface IjentOpenedFile {
|
||||
}
|
||||
|
||||
interface Writer : IjentOpenedFile {
|
||||
/**
|
||||
* TODO Document
|
||||
*
|
||||
* It writes not more than [com.intellij.platform.ijent.spi.RECOMMENDED_MAX_PACKET_SIZE].
|
||||
*/
|
||||
suspend fun write(buf: ByteBuffer): IjentFsResult<
|
||||
Int,
|
||||
WriteError>
|
||||
|
||||
/**
|
||||
* TODO Document
|
||||
*
|
||||
* It writes not more than [com.intellij.platform.ijent.spi.RECOMMENDED_MAX_PACKET_SIZE].
|
||||
*/
|
||||
suspend fun write(buf: ByteBuffer, pos: Long): IjentFsResult<
|
||||
Int,
|
||||
WriteError>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.platform.ijent.spi
|
||||
|
||||
/**
|
||||
* A soft limit for a single message size. It can be applied to tunnels, file reading and writing, etc.
|
||||
*
|
||||
* The API implementation should apply this limit itself, so API users may know nothing about this constant.
|
||||
* Moreover, API users are not supposed to fragment packets with this constant, because the API implementation would do that again.
|
||||
*
|
||||
* It's a good practice to use this limit for sending data chunks to IJent,
|
||||
* because the other side of communication may be a machine with little RAM,
|
||||
* and creating hundreds of megabytes of packets can be undesirable.
|
||||
*
|
||||
* Also, it's known that the gRPC implementation has a hard limit for _incoming_ messages, so this constant should be used in
|
||||
* requests to mitigate huge responses.
|
||||
*
|
||||
* It's acceptable if the message exceeds this limit for a few kilobytes.
|
||||
*
|
||||
* 131072 is 2^17 -- this number is chosen with no research, just a wild guess.
|
||||
* It may be changed if necessary, but it must not be close to the timeout from `io.grpc.internal.MessageDeframer.processHeader`
|
||||
*/
|
||||
const val RECOMMENDED_MAX_PACKET_SIZE = 131_072
|
||||
Reference in New Issue
Block a user