Output panel optimisation (#1058)

* test interval for output panel

* create buffer provider

* output panel buffer corrections

* output buffer cleanup

* code cleanup
This commit is contained in:
David Simpson 2022-06-14 13:00:20 +02:00 committed by GitHub
parent a8047660a6
commit 4c6243176c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 83 additions and 24 deletions

View File

@ -25,7 +25,9 @@ import { firstToUpperCase, firstToLowerCase } from '../common/utils';
import { Port } from './cli-protocol/cc/arduino/cli/commands/v1/port_pb';
import { nls } from '@theia/core';
import { MonitorManager } from './monitor-manager';
import { SimpleBuffer } from './utils/simple-buffer';
const FLUSH_OUTPUT_MESSAGES_TIMEOUT_MS = 32;
@injectable()
export class CoreServiceImpl extends CoreClientAware implements CoreService {
@inject(ResponseService)
@ -73,18 +75,25 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
this.mergeSourceOverrides(compileReq, options);
const result = client.compile(compileReq);
const compileBuffer = new SimpleBuffer(
this.flushOutputPanelMessages.bind(this),
FLUSH_OUTPUT_MESSAGES_TIMEOUT_MS
);
try {
await new Promise<void>((resolve, reject) => {
result.on('data', (cr: CompileResponse) => {
this.responseService.appendToOutput({
chunk: Buffer.from(cr.getOutStream_asU8()).toString(),
});
this.responseService.appendToOutput({
chunk: Buffer.from(cr.getErrStream_asU8()).toString(),
});
compileBuffer.addChunk(cr.getOutStream_asU8());
compileBuffer.addChunk(cr.getErrStream_asU8());
});
result.on('error', (error) => {
compileBuffer.clearFlushInterval();
reject(error);
});
result.on('end', () => {
compileBuffer.clearFlushInterval();
resolve();
});
result.on('error', (error) => reject(error));
result.on('end', () => resolve());
});
this.responseService.appendToOutput({
chunk: '\n--------------------------\nCompilation complete.\n',
@ -174,18 +183,24 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
const result = responseHandler(client, req);
const uploadBuffer = new SimpleBuffer(
this.flushOutputPanelMessages.bind(this),
FLUSH_OUTPUT_MESSAGES_TIMEOUT_MS
);
try {
await new Promise<void>((resolve, reject) => {
result.on('data', (resp: UploadResponse) => {
this.responseService.appendToOutput({
chunk: Buffer.from(resp.getOutStream_asU8()).toString(),
});
this.responseService.appendToOutput({
chunk: Buffer.from(resp.getErrStream_asU8()).toString(),
});
uploadBuffer.addChunk(resp.getOutStream_asU8());
uploadBuffer.addChunk(resp.getErrStream_asU8());
});
result.on('error', (error) => {
uploadBuffer.clearFlushInterval();
reject(error);
});
result.on('end', () => {
uploadBuffer.clearFlushInterval();
resolve();
});
result.on('error', (error) => reject(error));
result.on('end', () => resolve());
});
this.responseService.appendToOutput({
chunk:
@ -238,18 +253,25 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
burnReq.setVerify(options.verify);
burnReq.setVerbose(options.verbose);
const result = client.burnBootloader(burnReq);
const bootloaderBuffer = new SimpleBuffer(
this.flushOutputPanelMessages.bind(this),
FLUSH_OUTPUT_MESSAGES_TIMEOUT_MS
);
try {
await new Promise<void>((resolve, reject) => {
result.on('data', (resp: BurnBootloaderResponse) => {
this.responseService.appendToOutput({
chunk: Buffer.from(resp.getOutStream_asU8()).toString(),
});
this.responseService.appendToOutput({
chunk: Buffer.from(resp.getErrStream_asU8()).toString(),
});
bootloaderBuffer.addChunk(resp.getOutStream_asU8());
bootloaderBuffer.addChunk(resp.getErrStream_asU8());
});
result.on('error', (error) => {
bootloaderBuffer.clearFlushInterval();
reject(error);
});
result.on('end', () => {
bootloaderBuffer.clearFlushInterval();
resolve();
});
result.on('error', (error) => reject(error));
result.on('end', () => resolve());
});
} catch (e) {
const errorMessage = nls.localize(
@ -281,4 +303,10 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
}
}
}
private flushOutputPanelMessages(chunk: string): void {
this.responseService.appendToOutput({
chunk,
});
}
}

View File

@ -0,0 +1,31 @@
export class SimpleBuffer {
private chunks: Uint8Array[] = [];
private flushInterval?: NodeJS.Timeout;
constructor(onFlush: (chunk: string) => void, flushTimeout: number) {
this.flushInterval = setInterval(() => {
if (this.chunks.length > 0) {
const chunkString = Buffer.concat(this.chunks).toString();
this.clearChunks();
onFlush(chunkString);
}
}, flushTimeout);
}
public addChunk(chunk: Uint8Array): void {
this.chunks.push(chunk);
}
private clearChunks(): void {
this.chunks = [];
}
public clearFlushInterval(): void {
this.clearChunks();
clearInterval(this.flushInterval);
this.flushInterval = undefined;
}
}