3737import java .util .LinkedHashMap ;
3838import java .util .List ;
3939import java .util .Map ;
40- import java .util .concurrent . ConcurrentHashMap ;
40+ import java .util .Optional ;
4141import java .util .concurrent .CountDownLatch ;
42- import java .util .concurrent .TimeUnit ;
4342import java .util .concurrent .atomic .AtomicBoolean ;
4443
4544@ Slf4j
@@ -51,6 +50,7 @@ public class QueryConsole extends AbstractConsole {
5150 private StateManager <QueryConsoleState > stateManager ;
5251 private final Map <String , DataView > dataViews = new HashMap <>();
5352 private volatile Map <String , String > allowedContexts = Map .of ();
53+ private final SQLChunkTransferManager sqlChunkTransfers = new SQLChunkTransferManager ();
5454
5555 private static final Gson GSON = new Gson ();
5656
@@ -168,7 +168,7 @@ private void onAction(QueryConsoleAction action) {
168168 this .handleSQLChunk (action );
169169 }
170170 case QueryConsoleAction .ACTION_RUN_SQL_COMPLETE -> {
171- this .handleSQLComplete ();
171+ this .handleSQLComplete (action );
172172 }
173173
174174 case QueryConsoleAction .ACTION_RUN_SQL_FILE -> {
@@ -184,6 +184,7 @@ private void onAction(QueryConsoleAction action) {
184184
185185
186186 case QueryConsoleAction .ACTION_CANCEL -> {
187+ this .sqlChunkTransfers .cancelAll ();
187188 this .onCancel ();
188189 this .getState ().setInQuery (false );
189190 this .stateManager .commit ();
@@ -195,65 +196,26 @@ private void onAction(QueryConsoleAction action) {
195196 }
196197 }
197198
198- private final ConcurrentHashMap <Integer , String > sqlChunks = new ConcurrentHashMap <>();
199- private CountDownLatch latch ;
200- private int expectedChunks = -1 ;
201-
202199 private void handleSQLChunk (QueryConsoleAction action ) {
203- var data = (Map <String , Object >) action .getData ();
204- var chunk = (String ) data .get ("chunk" );
205- var index = (Integer ) data .get ("index" );
206- var total = (Integer ) data .get ("total" );
207-
208- synchronized (this ) {
209- if (expectedChunks == -1 ) {
210- expectedChunks = total ;
211- latch = new CountDownLatch (total );
212- }
213- }
214-
215- if (sqlChunks .putIfAbsent (index , chunk ) == null ) {
216- latch .countDown ();
200+ Optional <String > sql ;
201+ try {
202+ sql = this .sqlChunkTransfers .receiveChunk (action .getData ());
203+ } catch (IllegalArgumentException | IllegalStateException e ) {
204+ this .getConsoleLogger ().error ("Invalid SQL chunk transfer: %s" , e .getMessage ());
205+ return ;
217206 }
207+ sql .ifPresent (this ::onSQL );
218208 }
219209
220- /**
221- * 处理分段 SQL 接收完成
222- */
223- private void handleSQLComplete () {
210+ private void handleSQLComplete (QueryConsoleAction action ) {
211+ Optional <String > sql ;
224212 try {
225-
226- // 等待所有分段接收完成
227- boolean completed = latch .await (10 , TimeUnit .SECONDS ); // 超时10秒
228-
229- if (!completed ) {
230- this .getConsoleLogger ().error ("read sql message timeout!!" );
231- return ;
232- }
233-
234- // 按照索引顺序合并所有分段
235- StringBuilder sqlBuilder = new StringBuilder ();
236- for (int i = 0 ; i < expectedChunks ; i ++) {
237- sqlBuilder .append (sqlChunks .get (i ));
238- }
239-
240- // 合并完成后清理缓存
241- var sql = sqlBuilder .toString ();
242- sqlChunks .clear ();
243- expectedChunks = -1 ;
244-
245- // 执行完整 SQL
246- this .getState ().setInQuery (true );
247- this .stateManager .commit ();
248-
249- this .onSQL (sql );
250-
251- } catch (InterruptedException e ) {
252- Thread .currentThread ().interrupt ();
253- } finally {
254- this .getState ().setInQuery (false );
255- this .stateManager .commit ();
213+ sql = this .sqlChunkTransfers .receiveComplete (action .getData ());
214+ } catch (IllegalArgumentException | IllegalStateException e ) {
215+ this .getConsoleLogger ().error ("Invalid SQL chunk transfer: %s" , e .getMessage ());
216+ return ;
256217 }
218+ sql .ifPresent (this ::onSQL );
257219 }
258220
259221 private void onDataViewAction (DataViewAction action ) {
@@ -538,6 +500,7 @@ private void sendDataView(DataView dataView, boolean clearOthers) {
538500
539501 @ Override
540502 public void close () {
503+ this .sqlChunkTransfers .close ();
541504 if (this .currentPlan != null ) {
542505 // flush
543506 var session = SessionManager .getCurrentSession ();
0 commit comments