Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge Task Server & Build Server #1512

Merged
merged 37 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
9006161
merge
Jiaaming Apr 29, 2024
bbe05ef
merge server
Jiaaming Jul 1, 2024
7f79375
merge both server
Jiaaming Jul 1, 2024
bfac717
fix lint
Jiaaming Jul 1, 2024
b1e2962
fix generateRandomPipeName
Jiaaming Jul 2, 2024
42f3a9f
refine named pipe repost design
Jiaaming Jul 2, 2024
38038da
refine jdk search logic
Jiaaming Jul 3, 2024
1d916bb
update messageProxy, add error handling for task server, fix bugs
Jiaaming Jul 3, 2024
29aa9ef
fix nit
Jiaaming Jul 3, 2024
d60ff9f
fix nit
Jiaaming Jul 3, 2024
383aabc
Merge remote-tracking branch 'origin' into merge-with-named-pipe
Jiaaming Jul 4, 2024
1f8122f
fix comments
Jiaaming Jul 4, 2024
58b85f8
expand jdk search logic and fix comments
Jiaaming Jul 5, 2024
d713497
fix typo
Jiaaming Jul 5, 2024
c117618
fix typo
Jiaaming Jul 5, 2024
d0ec674
fix comments
Jiaaming Jul 5, 2024
a097a87
fix comments
Jiaaming Jul 5, 2024
5f7b4d7
Merge branch 'develop' into merge-with-named-pipe
jdneo Jul 5, 2024
c629a81
Merge branch 'develop' into merge-with-named-pipe
Jiaaming Jul 10, 2024
c201306
1. Add local build-server-for-gradle jar import and related gradle bu…
Jiaaming Jul 10, 2024
609a781
Fix: handle empty param in bspProxy repost
Jiaaming Jul 10, 2024
f582668
Fix: comments
Jiaaming Jul 11, 2024
9365ac6
Merge branch 'develop' into merge-with-named-pipe
Jiaaming Jul 11, 2024
9214957
1.Fix: comment
Jiaaming Jul 12, 2024
d7e3668
1.Add error handle for rpc connection
Jiaaming Jul 15, 2024
807f9a9
Fix: typo
Jiaaming Jul 16, 2024
9deaeb6
1.Update github workflow to feat local dependency
Jiaaming Jul 17, 2024
6f1701f
Update: lint ignore
Jiaaming Jul 17, 2024
3291eb6
fix: powermock jdk17
Jiaaming Jul 17, 2024
b2eaba7
Merge branch 'develop' into merge-with-named-pipe
jdneo Jul 19, 2024
8b5e1d9
Refine jdk search logic that start gradle-server
Jiaaming Jul 19, 2024
b3c13e3
Fix: comments
Jiaaming Jul 19, 2024
d59d605
Fix: comment
Jiaaming Jul 19, 2024
7507a3c
fix comments
Jiaaming Jul 22, 2024
7446361
Fix: comment
Jiaaming Jul 22, 2024
722406a
Fix: build.gradle file
Jiaaming Jul 22, 2024
be63f6d
Fix: extension start sequence
Jiaaming Jul 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class NamedPipeStream {

private StreamProvider provider;

private final int MAX_ATTEMPTS = 5;
interface StreamProvider {
InputStream getInputStream() throws IOException;

Expand Down Expand Up @@ -55,35 +56,47 @@ public OutputStream getOutputStream() throws IOException {
private void initializeNamedPipe() {
String pathName = generateRandomPipeName();
sendImporterPipeName(pathName);

File pipeFile = new File(pathName);

// Need to retry until the pipeName was sent and pipe is created by Extension side
int attempts = 0;
boolean connected = false;
while (!connected) {
try{
if (isWindows()) {
AsynchronousFileChannel channel = AsynchronousFileChannel.open(pipeFile.toPath(),
StandardOpenOption.READ, StandardOpenOption.WRITE);
input = new NamedPipeInputStream(channel);
output = new NamedPipeOutputStream(channel);
} else {
UnixDomainSocketAddress socketAddress = UnixDomainSocketAddress.of(pipeFile.toPath());
SocketChannel channel = SocketChannel.open(StandardProtocolFamily.UNIX);
channel.connect(socketAddress);
input = new NamedPipeInputStream(channel);
output = new NamedPipeOutputStream(channel);
}
// Need to retry until the pipeName was sent and pipe is created by Extension side
while (!connected && attempts < MAX_ATTEMPTS) {
try {
attemptConnection(pipeFile);
Jiaaming marked this conversation as resolved.
Show resolved Hide resolved
connected = true;
} catch (IOException e) {
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RuntimeException("Thread interrupted while trying to connect to named pipe", ie);
}
handleConnectionFailure(e, attempts);
attempts++;
}
}
if (!connected) {
Jiaaming marked this conversation as resolved.
Show resolved Hide resolved
throw new RuntimeException("Failed to connect after " + MAX_ATTEMPTS + " attempts.");
}
}

private void attemptConnection(File pipeFile) throws IOException {
if (isWindows()) {
AsynchronousFileChannel channel = AsynchronousFileChannel.open(pipeFile.toPath(),
StandardOpenOption.READ, StandardOpenOption.WRITE);
input = new NamedPipeInputStream(channel);
output = new NamedPipeOutputStream(channel);
} else {
UnixDomainSocketAddress socketAddress = UnixDomainSocketAddress.of(pipeFile.toPath());
SocketChannel channel = SocketChannel.open(StandardProtocolFamily.UNIX);
channel.connect(socketAddress);
input = new NamedPipeInputStream(channel);
output = new NamedPipeOutputStream(channel);
}
}

private void handleConnectionFailure(IOException e, int attempts) {
Jiaaming marked this conversation as resolved.
Show resolved Hide resolved
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RuntimeException("Thread interrupted while handling connection failure", ie);
}
}
}

Expand Down Expand Up @@ -202,6 +215,7 @@ public InputStream getInputStream() throws IOException {
}

public OutputStream getOutputStream() throws IOException {

Jiaaming marked this conversation as resolved.
Show resolved Hide resolved
return getSelectedStream().getOutputStream();
}

Expand All @@ -214,7 +228,7 @@ private void sendImporterPipeName(String pipeName){
.sendNotification("gradle.getImporterPipeName", pipeName);
}

public static String generateRandomHex(int numBytes) {
private static String generateRandomHex(int numBytes) {
SecureRandom random = new SecureRandom();
byte[] bytes = new byte[numBytes];
random.nextBytes(bytes);
Expand All @@ -225,7 +239,7 @@ public static String generateRandomHex(int numBytes) {
return hexString.toString();
}

public String generateRandomPipeName() {
private String generateRandomPipeName() {
Jiaaming marked this conversation as resolved.
Show resolved Hide resolved
if (System.getProperty("os.name").startsWith("Windows")) {
return Paths.get("\\\\.\\pipe\\", generateRandomHex(16) + "-sock").toString();
}
Expand Down
8 changes: 0 additions & 8 deletions extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,6 @@
"dark": "resources/dark/run.svg"
}
},
{
"command": "gradle.getBundleDirectory",
"title": "Get Build Server Port"
},
{
"command": "gradle.getBundlePath",
"title": "Get Build Server Port"
},
{
"command": "gradle.runBuild",
"category": "Gradle",
Expand Down
17 changes: 5 additions & 12 deletions extension/src/Extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,13 @@ import {
GRADLE_COMPLETION,
GRADLE_PROPERTIES_FILE_CHANGE,
VSCODE_TRIGGER_COMPLETION,
GET_EXTENSION_PATH,
} from "./constant";
import { instrumentOperation, sendInfo } from "vscode-extension-telemetry-wrapper";
import { GradleBuildContentProvider } from "./client/GradleBuildContentProvider";
import { BuildServerController } from "./bs/BuildServerController";
import { MessageForwardHandler } from "./bs/MessageForwardHandler";
import { MessageProxy } from "./bs/MessageProxy";
export class Extension {
private readonly messageForwardHandler: MessageForwardHandler;
private readonly messageProxy: MessageProxy;
private readonly client: GradleClient;
private readonly server: GradleServer;
private readonly pinnedTasksStore: PinnedTasksStore;
Expand Down Expand Up @@ -83,14 +82,8 @@ export class Extension {
}

const statusBarItem = vscode.window.createStatusBarItem();
this.context.subscriptions.push(
vscode.commands.registerCommand(GET_EXTENSION_PATH, () => {
return this.context.extensionPath;
})
);

this.messageForwardHandler = new MessageForwardHandler(this.context);
this.server = new GradleServer({ host: "localhost" }, context, serverLogger, this.messageForwardHandler);
this.messageProxy = new MessageProxy(this.context);
this.server = new GradleServer({ host: "localhost" }, context, serverLogger, this.messageProxy);
this.client = new GradleClient(this.server, statusBarItem, clientLogger);
this.pinnedTasksStore = new PinnedTasksStore(context);
this.recentTasksStore = new RecentTasksStore();
Expand Down Expand Up @@ -238,7 +231,7 @@ export class Extension {
if (!this.server.isReady()) {
await this.server.start();
}
await this.messageForwardHandler.startForwarding();
await this.messageProxy.start();
await vscode.commands.executeCommand("setContext", "gradle:activated", activated);
await vscode.commands.executeCommand("setContext", "gradle:defaultView", true);
}
Expand Down
33 changes: 33 additions & 0 deletions extension/src/bs/BuildServerConnector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import * as net from "net";
import * as rpc from "vscode-jsonrpc/node";
import { generateRandomPipeName } from "../util/generateRandomPipeName";

export class BuildServerConnector {
Jiaaming marked this conversation as resolved.
Show resolved Hide resolved
private serverConnection: rpc.MessageConnection | null = null;
private serverPipeServer: net.Server;
private serverPipePath: string;

constructor() {
this.setupServer();
}

private setupServer(): void {
Jiaaming marked this conversation as resolved.
Show resolved Hide resolved
this.serverPipePath = generateRandomPipeName();
this.serverPipeServer = net.createServer((socket: net.Socket) => {
this.serverConnection = rpc.createMessageConnection(
new rpc.StreamMessageReader(socket),
new rpc.StreamMessageWriter(socket)
);
this.serverConnection.listen();
});
this.serverPipeServer.listen(this.serverPipePath);
}

public getServerConnection(): rpc.MessageConnection | null {
return this.serverConnection;
}

public getServerPipePath(): string {
return this.serverPipePath;
}
}
52 changes: 52 additions & 0 deletions extension/src/bs/JdtlsImporterConnector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import * as net from "net";
import * as rpc from "vscode-jsonrpc/node";
import * as vscode from "vscode";
import * as path from "path";

export const GET_IMPORTER_PIPE_NAME = "gradle.getImporterPipeName";

export class JdtlsImporterConnector {
Jiaaming marked this conversation as resolved.
Show resolved Hide resolved
private importerConnection: rpc.MessageConnection | null = null;
private importerPipeServer: net.Server;
private importerPipePath: string;
private readonly context: vscode.ExtensionContext;

constructor(context: vscode.ExtensionContext) {
this.context = context;
}

//receive the pipe name from Java jdt.ls importer
public async waitForImporterPipePath(): Promise<void> {
return new Promise((resolve) => {
this.context.subscriptions.push(
vscode.commands.registerCommand(GET_IMPORTER_PIPE_NAME, (pipeName: string) => {
this.importerPipePath = path.resolve(pipeName);
Jiaaming marked this conversation as resolved.
Show resolved Hide resolved
resolve();
})
);
});
}

public setupImporterServer(buildServerConnection: rpc.MessageConnection | null): void {
this.importerPipeServer = net.createServer((socket: net.Socket) => {
this.importerConnection = rpc.createMessageConnection(
new rpc.StreamMessageReader(socket),
new rpc.StreamMessageWriter(socket)
);
this.setupMessageForwarding(buildServerConnection);
this.importerConnection.listen();
});
this.importerPipeServer.listen(this.importerPipePath);
}

private setupMessageForwarding(buildServerConnection: rpc.MessageConnection | null): void {
Jiaaming marked this conversation as resolved.
Show resolved Hide resolved
const importerConnection = this.importerConnection;

importerConnection?.onRequest((method, params) => {
return buildServerConnection?.sendRequest(method, params);
});
buildServerConnection?.onNotification((method, params) => {
importerConnection?.sendNotification(method, params);
});
}
}
75 changes: 0 additions & 75 deletions extension/src/bs/MessageForwardHandler.ts

This file was deleted.

21 changes: 21 additions & 0 deletions extension/src/bs/MessageProxy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { JdtlsImporterConnector } from "./JdtlsImporterConnector";
import { BuildServerConnector } from "./BuildServerConnector";
import * as vscode from "vscode";

export class MessageProxy {
Jiaaming marked this conversation as resolved.
Show resolved Hide resolved
Jiaaming marked this conversation as resolved.
Show resolved Hide resolved
private buildServerConnector: BuildServerConnector;
private jdtlsImporterConnector: JdtlsImporterConnector;

constructor(context: vscode.ExtensionContext) {
this.buildServerConnector = new BuildServerConnector();
this.jdtlsImporterConnector = new JdtlsImporterConnector(context);
}

public async start(): Promise<void> {
await this.jdtlsImporterConnector.waitForImporterPipePath();
this.jdtlsImporterConnector.setupImporterServer(this.buildServerConnector.getServerConnection());
}
public getBuildServerPipeName(): string {
return this.buildServerConnector.getServerPipePath();
}
}
1 change: 0 additions & 1 deletion extension/src/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
export namespace Context {
export const ACTIVATION_CONTEXT_KEY = "gradle:extensionActivated";
}
export const GET_EXTENSION_PATH = "gradle.getExtensionPath";

export const GRADLE_BUILD_FILE_CHANGE = "gradle.buildFileChanged";

Expand Down
Loading