Skip to content

Conversation

junhaoliao
Copy link
Member

@junhaoliao junhaoliao commented Jul 8, 2025

Description

See the analysis at #1062 . This PR implements "Approach 5" which is the final recommendation.

Checklist

  • The PR satisfies the contribution guidelines.
  • This is a breaking change and that has been indicated in the PR title, OR this isn't a
    breaking change.
  • Necessary docs have been updated, OR no docs need to be updated.

Validation performed

On Windows:

  1. Installed Docker Desktop for Windows. "Enable host networking" in the Settings -> Resources -> Network.
  2. Within a WSL 2 VM (Ubuntu Jammy), added the default user to the docker group: sudo usermod -aG docker "$USER".

Within the WSL VM:

  1. Built the package: task
  2. Started the package: cd build/clp-package/sbin; ./start-clp.sh
  3. Compressed sample logs: ./compress.sh ~/sample/hive-24hr/i-00c90a0f/
  4. Launched the WebUI in a browser: http://localhost:4000/search . Performed a search with query string being "1" and observed "found 29099 results" in the UI within a second of query submission.
  5. Repeated Step 4 with http://127.0.0.1:4000/search and observed the same results.
  6. Repeated Step 4 with http://[::1]:4000/search and observed the same results.

Summary by CodeRabbit

  • New Features
    • Enhanced server to proxy socket.io requests across multiple IP addresses, including IPv4 and IPv6, ensuring seamless connectivity.
  • Chores
    • Added a dependency to support HTTP proxy functionality.

@junhaoliao junhaoliao requested a review from a team as a code owner July 8, 2025 00:25
Copy link
Contributor

coderabbitai bot commented Jul 8, 2025

Walkthrough

The changes update the webui-server's dependencies by adding the @fastify/http-proxy package and modify the MongoSocketIoServer class to perform DNS lookups for the configured host. If multiple addresses are found, HTTP proxy logic is added to forward socket.io requests appropriately.

Changes

File(s) Change Summary
components/webui/server/package.json Added @fastify/http-proxy dependency at version ^11.3.0.
components/webui/server/src/plugins/MongoSocketIoServer/... Added DNS lookup in static create method; if multiple addresses found, registers Fastify HTTP proxy for /socket.io/.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant FastifyServer
    participant DNS
    participant MongoSocketIoServer

    User->>FastifyServer: Sends request to /socket.io/
    FastifyServer->>MongoSocketIoServer: Handles initialization
    MongoSocketIoServer->>DNS: Performs lookup for configured host (all addresses)
    DNS-->>MongoSocketIoServer: Returns list of IP addresses
    alt Multiple addresses found
        MongoSocketIoServer->>FastifyServer: Registers HTTP proxy for /socket.io/
        User->>FastifyServer: Request on secondary address
        FastifyServer->>FastifyServer: Proxies request to main server address
    else Single address found
        User->>FastifyServer: Request handled normally
    end
Loading

Possibly related PRs

Suggested reviewers

  • haiqi96

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2bd7696 and b18ace4.

📒 Files selected for processing (1)
  • components/webui/server/src/plugins/MongoSocketIoServer/index.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}`: - Prefer `false == ` rather than `!`.

**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}: - Prefer false == <expression> rather than !<expression>.

⚙️ Source: CodeRabbit Configuration File

List of files the instruction was applied to:

  • components/webui/server/src/plugins/MongoSocketIoServer/index.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:32-38
Timestamp: 2025-05-09T18:05:42.814Z
Learning: When implementing Socket.IO namespaces or connection pooling in a client-server architecture (like the MongoDB collection socket system in the log-viewer-webui), coordinated changes are needed on both client and server sides, making it appropriate to track as a TODO rather than implement piecemeal.
Learnt from: junhaoliao
PR: y-scope/clp#939
File: components/package-template/src/etc/clp-config.yml:64-64
Timestamp: 2025-06-22T04:01:43.409Z
Learning: The new webui architecture uses Fastify with Pino logging instead of the previous Winston-based logging system that was removed during the webui refactoring.
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:27-31
Timestamp: 2025-05-09T19:15:26.180Z
Learning: For the MongoDB real-time updates implementation in components/log-viewer-webui/client/src/api/socket, a socket singleton pattern is used where a single shared socket connection is maintained rather than creating multiple connections. The socket lifecycle is managed centrally, with unsubscription handling in the useCursor React hook's cleanup function.
components/webui/server/src/plugins/MongoSocketIoServer/index.ts (6)
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:32-38
Timestamp: 2025-05-09T18:05:42.814Z
Learning: When implementing Socket.IO namespaces or connection pooling in a client-server architecture (like the MongoDB collection socket system in the log-viewer-webui), coordinated changes are needed on both client and server sides, making it appropriate to track as a TODO rather than implement piecemeal.
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:27-31
Timestamp: 2025-05-09T19:15:26.180Z
Learning: For the MongoDB real-time updates implementation in components/log-viewer-webui/client/src/api/socket, a socket singleton pattern is used where a single shared socket connection is maintained rather than creating multiple connections. The socket lifecycle is managed centrally, with unsubscription handling in the useCursor React hook's cleanup function.
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
Learnt from: junhaoliao
PR: y-scope/clp#899
File: components/log-viewer-webui/server/src/main.ts:50-58
Timestamp: 2025-05-13T19:38:31.164Z
Learning: When using Fastify's `app.close()` method, always wrap it in a try/catch block to properly handle shutdown errors. The close() method returns a Promise that can reject if errors occur during the shutdown process (especially with plugins using onClose hooks), and unhandled rejections could cause the application to hang.
Learnt from: junhaoliao
PR: y-scope/clp#1078
File: components/webui/server/src/plugins/MongoSocketIoServer/index.ts:105-108
Timestamp: 2025-07-08T17:20:02.560Z
Learning: The y-scope/clp codebase has a 100-character line length limit that takes precedence over other style preferences like template literals when they conflict.
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:35-41
Timestamp: 2024-11-19T19:52:43.429Z
Learning: For internal APIs in `components/log-viewer-webui/client/src/api/query.js`, runtime validation of parameters may not be necessary since the APIs are not exposed to end users, and JsDoc type annotations may be sufficient.
🪛 Biome (1.9.4)
components/webui/server/src/plugins/MongoSocketIoServer/index.ts

[error] 107-109: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3779a4c and 12c2304.

⛔ Files ignored due to path filters (1)
  • components/webui/server/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (2)
  • components/webui/server/package.json (1 hunks)
  • components/webui/server/src/plugins/MongoSocketIoServer/index.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}`: - Prefer `false == ` rather than `!`.

**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}: - Prefer false == <expression> rather than !<expression>.

⚙️ Source: CodeRabbit Configuration File

List of files the instruction was applied to:

  • components/webui/server/src/plugins/MongoSocketIoServer/index.ts
🧠 Learnings (3)
📓 Common learnings
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:32-38
Timestamp: 2025-05-09T18:05:42.814Z
Learning: When implementing Socket.IO namespaces or connection pooling in a client-server architecture (like the MongoDB collection socket system in the log-viewer-webui), coordinated changes are needed on both client and server sides, making it appropriate to track as a TODO rather than implement piecemeal.
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
Learnt from: junhaoliao
PR: y-scope/clp#939
File: components/package-template/src/etc/clp-config.yml:64-64
Timestamp: 2025-06-22T04:01:43.409Z
Learning: The new webui architecture uses Fastify with Pino logging instead of the previous Winston-based logging system that was removed during the webui refactoring.
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:27-31
Timestamp: 2025-05-09T19:15:26.180Z
Learning: For the MongoDB real-time updates implementation in components/log-viewer-webui/client/src/api/socket, a socket singleton pattern is used where a single shared socket connection is maintained rather than creating multiple connections. The socket lifecycle is managed centrally, with unsubscription handling in the useCursor React hook's cleanup function.
components/webui/server/src/plugins/MongoSocketIoServer/index.ts (4)
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:32-38
Timestamp: 2025-05-09T18:05:42.814Z
Learning: When implementing Socket.IO namespaces or connection pooling in a client-server architecture (like the MongoDB collection socket system in the log-viewer-webui), coordinated changes are needed on both client and server sides, making it appropriate to track as a TODO rather than implement piecemeal.
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:27-31
Timestamp: 2025-05-09T19:15:26.180Z
Learning: For the MongoDB real-time updates implementation in components/log-viewer-webui/client/src/api/socket, a socket singleton pattern is used where a single shared socket connection is maintained rather than creating multiple connections. The socket lifecycle is managed centrally, with unsubscription handling in the useCursor React hook's cleanup function.
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
Learnt from: junhaoliao
PR: y-scope/clp#899
File: components/log-viewer-webui/server/src/main.ts:50-58
Timestamp: 2025-05-13T19:38:31.164Z
Learning: When using Fastify's `app.close()` method, always wrap it in a try/catch block to properly handle shutdown errors. The close() method returns a Promise that can reject if errors occur during the shutdown process (especially with plugins using onClose hooks), and unhandled rejections could cause the application to hang.
components/webui/server/package.json (2)
Learnt from: junhaoliao
PR: y-scope/clp#939
File: components/package-template/src/etc/clp-config.yml:64-64
Timestamp: 2025-06-22T04:01:43.409Z
Learning: The new webui architecture uses Fastify with Pino logging instead of the previous Winston-based logging system that was removed during the webui refactoring.
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
🪛 Biome (1.9.4)
components/webui/server/src/plugins/MongoSocketIoServer/index.ts

[error] 102-104: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: lint-check (ubuntu-latest)
  • GitHub Check: lint-check (macos-latest)
🔇 Additional comments (2)
components/webui/server/package.json (1)

28-28: LGTM! Dependency addition looks appropriate.

The @fastify/http-proxy dependency is correctly added to support the HTTP proxy functionality for socket.io requests. The version constraint ^11.3.0 follows semantic versioning best practices.

components/webui/server/src/plugins/MongoSocketIoServer/index.ts (1)

7-9: LGTM! Clean import additions.

The imports for DNS lookup and HTTP proxy functionality are correctly added and follow the existing import structure.

Comment on lines 84 to 112

// Fastify listens on all resolved addresses for localhost (e.g. `127.0.0.1`, `::1`), but
// socket.io only uses the main one. When multiple addresses are resolved, we proxy
// socket.io requests from secondary addresses to the main server.
dnsLookup(fastify.config.HOST, {all: true}, (err, addresses) => {
if (null !== err) {
fastify.log.error(`DNS lookup failed: ${err.message}`);

return;
}
const [firstAddress] = addresses;
if ("undefined" === typeof firstAddress) {
fastify.log.error("No addresses found for the provided host.");

return;
}
if (1 < addresses.length) {
fastify.log.warn(
`Multiple addresses found for ${fastify.config.HOST}: ${
JSON.stringify(addresses)}. ` +
"Proxying all socket.io requests to the main server."
);
fastify.register(fastifyHttpProxy, {
upstream: `http://${fastify.config.HOST}:${fastify.config.PORT}/socket.io/`,
prefix: "/socket.io/",
});
}
});

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Fix potential circular proxy issue and improve string concatenation.

The DNS lookup implementation is well-structured with proper error handling, but there are two issues:

  1. Circular proxy concern: The proxy upstream points to the same HOST:PORT that's already being used by the server, which could create a circular proxy loop.

  2. String concatenation: Use template literals instead of string concatenation for better readability.

Apply this diff to address the template literal issue:

-                fastify.log.warn(
-                    `Multiple addresses found for ${fastify.config.HOST}: ${
-                        JSON.stringify(addresses)}. ` +
-                    "Proxying all socket.io requests to the main server."
-                );
+                fastify.log.warn(
+                    `Multiple addresses found for ${fastify.config.HOST}: ${
+                        JSON.stringify(addresses)}. ` +
+                    `Proxying all socket.io requests to the main server.`
+                );

For the circular proxy issue, please verify the proxy configuration. The current setup proxies requests to the same server instance, which may not work as intended.

Run the following script to verify how the proxy configuration should work:


🏁 Script executed:

#!/bin/bash
# Description: Check the proxy configuration logic and examine similar implementations

# Look for other HTTP proxy usage patterns in the codebase
rg -A 10 -B 5 "fastifyHttpProxy|http-proxy" --type ts

# Check if there are any existing proxy configurations
rg -A 10 -B 5 "upstream.*socket\.io" --type ts

Length of output: 4803


Prevent circular proxy loops by proxying to the resolved IP and unify the log message

  • Replace the split string concatenation in fastify.log.warn with a single template literal.
  • Use the DNS‐resolved firstAddress.address for the upstream URL instead of fastify.config.HOST to avoid a proxy calling itself.

Apply this diff in components/webui/server/src/plugins/MongoSocketIoServer/index.ts:

@@ dnsLookup(fastify.config.HOST, {all: true}, (err, addresses) => {
-            if (1 < addresses.length) {
-                fastify.log.warn(
-                    `Multiple addresses found for ${fastify.config.HOST}: ${JSON.stringify(addresses)}. ` +
-                    "Proxying all socket.io requests to the main server."
-                );
-                fastify.register(fastifyHttpProxy, {
-                    upstream: `http://${fastify.config.HOST}:${fastify.config.PORT}/socket.io/`,
-                    prefix: "/socket.io/",
-                });
+            if (addresses.length > 1) {
+                const {address: mainAddress} = addresses[0];
+                fastify.log.warn(
+                    `Multiple addresses found for ${fastify.config.HOST}: ${JSON.stringify(addresses)}. ` +
+                    `Proxying all socket.io requests to ${mainAddress}:${fastify.config.PORT}.`
+                );
+                fastify.register(fastifyHttpProxy, {
+                    upstream: `http://${mainAddress}:${fastify.config.PORT}/socket.io/`,
+                    prefix: "/socket.io/",
+                });
             }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Fastify listens on all resolved addresses for localhost (e.g. `127.0.0.1`, `::1`), but
// socket.io only uses the main one. When multiple addresses are resolved, we proxy
// socket.io requests from secondary addresses to the main server.
dnsLookup(fastify.config.HOST, {all: true}, (err, addresses) => {
if (null !== err) {
fastify.log.error(`DNS lookup failed: ${err.message}`);
return;
}
const [firstAddress] = addresses;
if ("undefined" === typeof firstAddress) {
fastify.log.error("No addresses found for the provided host.");
return;
}
if (1 < addresses.length) {
fastify.log.warn(
`Multiple addresses found for ${fastify.config.HOST}: ${
JSON.stringify(addresses)}. ` +
"Proxying all socket.io requests to the main server."
);
fastify.register(fastifyHttpProxy, {
upstream: `http://${fastify.config.HOST}:${fastify.config.PORT}/socket.io/`,
prefix: "/socket.io/",
});
}
});
// Fastify listens on all resolved addresses for localhost (e.g. `127.0.0.1`, `::1`), but
// socket.io only uses the main one. When multiple addresses are resolved, we proxy
// socket.io requests from secondary addresses to the main server.
dnsLookup(fastify.config.HOST, {all: true}, (err, addresses) => {
if (null !== err) {
fastify.log.error(`DNS lookup failed: ${err.message}`);
return;
}
const [firstAddress] = addresses;
if ("undefined" === typeof firstAddress) {
fastify.log.error("No addresses found for the provided host.");
return;
}
if (addresses.length > 1) {
const { address: mainAddress } = addresses[0];
fastify.log.warn(
`Multiple addresses found for ${fastify.config.HOST}: ${JSON.stringify(addresses)}. ` +
`Proxying all socket.io requests to ${mainAddress}:${fastify.config.PORT}.`
);
fastify.register(fastifyHttpProxy, {
upstream: `http://${mainAddress}:${fastify.config.PORT}/socket.io/`,
prefix: "/socket.io/",
});
}
});
🧰 Tools
🪛 Biome (1.9.4)

[error] 102-104: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

🤖 Prompt for AI Agents
In components/webui/server/src/plugins/MongoSocketIoServer/index.ts between
lines 84 and 112, update the fastify.log.warn call to use a single template
literal instead of string concatenation for clarity. Also, change the upstream
URL in the fastifyHttpProxy registration to use the DNS-resolved
firstAddress.address instead of fastify.config.HOST to prevent circular proxy
loops by ensuring the proxy targets the actual resolved IP address.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (1)
components/webui/server/src/plugins/MongoSocketIoServer/index.ts (1)

103-106: Prefer template literals over string concatenation (duplicate of earlier feedback)

Same style issue previously pointed out in past reviews – switch to a single template literal.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 12c2304 and 4067548.

📒 Files selected for processing (1)
  • components/webui/server/src/plugins/MongoSocketIoServer/index.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}`: - Prefer `false == ` rather than `!`.

**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}: - Prefer false == <expression> rather than !<expression>.

⚙️ Source: CodeRabbit Configuration File

List of files the instruction was applied to:

  • components/webui/server/src/plugins/MongoSocketIoServer/index.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:32-38
Timestamp: 2025-05-09T18:05:42.814Z
Learning: When implementing Socket.IO namespaces or connection pooling in a client-server architecture (like the MongoDB collection socket system in the log-viewer-webui), coordinated changes are needed on both client and server sides, making it appropriate to track as a TODO rather than implement piecemeal.
Learnt from: junhaoliao
PR: y-scope/clp#939
File: components/package-template/src/etc/clp-config.yml:64-64
Timestamp: 2025-06-22T04:01:43.409Z
Learning: The new webui architecture uses Fastify with Pino logging instead of the previous Winston-based logging system that was removed during the webui refactoring.
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:27-31
Timestamp: 2025-05-09T19:15:26.180Z
Learning: For the MongoDB real-time updates implementation in components/log-viewer-webui/client/src/api/socket, a socket singleton pattern is used where a single shared socket connection is maintained rather than creating multiple connections. The socket lifecycle is managed centrally, with unsubscription handling in the useCursor React hook's cleanup function.
components/webui/server/src/plugins/MongoSocketIoServer/index.ts (4)
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:32-38
Timestamp: 2025-05-09T18:05:42.814Z
Learning: When implementing Socket.IO namespaces or connection pooling in a client-server architecture (like the MongoDB collection socket system in the log-viewer-webui), coordinated changes are needed on both client and server sides, making it appropriate to track as a TODO rather than implement piecemeal.
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:27-31
Timestamp: 2025-05-09T19:15:26.180Z
Learning: For the MongoDB real-time updates implementation in components/log-viewer-webui/client/src/api/socket, a socket singleton pattern is used where a single shared socket connection is maintained rather than creating multiple connections. The socket lifecycle is managed centrally, with unsubscription handling in the useCursor React hook's cleanup function.
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
Learnt from: junhaoliao
PR: y-scope/clp#899
File: components/log-viewer-webui/server/src/main.ts:50-58
Timestamp: 2025-05-13T19:38:31.164Z
Learning: When using Fastify's `app.close()` method, always wrap it in a try/catch block to properly handle shutdown errors. The close() method returns a Promise that can reject if errors occur during the shutdown process (especially with plugins using onClose hooks), and unhandled rejections could cause the application to hang.
🪛 Biome (1.9.4)
components/webui/server/src/plugins/MongoSocketIoServer/index.ts

[error] 104-106: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: lint-check (ubuntu-latest)
  • GitHub Check: lint-check (macos-latest)
  • GitHub Check: build (macos-latest)

@davemarco
Copy link
Contributor

I can't test this since mac (maybe @haiqi96), but from what you described the approach makes sense. Do we need this fix for the release?

JSON.stringify(addresses)}. ` +
"Proxying all socket.io requests to the main server."
);
fastify.register(fastifyHttpProxy, {
Copy link
Contributor

@davemarco davemarco Jul 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you may beable to get https/http from fastify.initialConfig.https, so not hardcoded at http

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't support HTTPS cert configuration in the Fastify server yet so this may not matter. still, i made the change to show the consideration.

until we add HTTPS support in the fastify server and disable HTTP when deployment maintainers configure so, it's recommended to protect the HTTP server with an HTTPS-enabled Nginx reverse proxy

// Fastify listens on all resolved addresses for localhost (e.g. `127.0.0.1`, `::1`), but
// socket.io only uses the main one. When multiple addresses are resolved, we proxy
// socket.io requests from secondary addresses to the main server.
dnsLookup(fastify.config.HOST, {all: true}, (err, addresses) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could potentially do this with fastify.addresses property instead, but you would need to call in the main.ts file and after fastify.listen(after plugin registration). Overall I think the approach you took where it is done in the this plugin is better.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, i believe the Fastify addresses info isn't available until fastify.listen() is called. also as you mentioned the proxy registration within this Mongo plugin was intentional.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
components/webui/server/src/plugins/MongoSocketIoServer/index.ts (1)

111-118: Proxy still loops back to itself + WebSocket upgrades not forwarded

  1. upstream targets ${fastify.config.HOST}:${fastify.config.PORT}, i.e. the very server that just registered the proxy. Every /socket.io request re-enters the proxy and creates an infinite loop.
  2. Socket.IO relies on WebSocket upgrades but @fastify/http-proxy only forwards them when websocket: true is set.
  3. Including /socket.io/ in upstream while also setting prefix: "/socket.io/" double-appends the path after Fastify strips the prefix.

Proposed fix:

-                const protocol = fastify.initialConfig.https ?
-                    "https" :
-                    "http";
-
-                fastify.register(fastifyHttpProxy, {
-                    upstream: `${protocol}://${fastify.config.HOST}:${fastify.config.PORT}/socket.io/`,
-                    prefix: "/socket.io/",
-                });
+                const [{address: primaryIp}] = addresses;          // break the self-proxy loop
+                const protocol = fastify.initialConfig.https ? "https" : "http";
+
+                fastify.register(fastifyHttpProxy, {
+                    upstream: `${protocol}://${primaryIp}:${fastify.config.PORT}`,
+                    prefix: "/socket.io/",
+                    websocket: true,                               // forward WS upgrades
+                });

This routes secondary-address traffic straight to the main listener, forwards WS handshakes, and avoids path duplication.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 96824c8 and 4bb266b.

📒 Files selected for processing (1)
  • components/webui/server/src/plugins/MongoSocketIoServer/index.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}`: - Prefer `false == ` rather than `!`.

**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}: - Prefer false == <expression> rather than !<expression>.

⚙️ Source: CodeRabbit Configuration File

List of files the instruction was applied to:

  • components/webui/server/src/plugins/MongoSocketIoServer/index.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:32-38
Timestamp: 2025-05-09T18:05:42.814Z
Learning: When implementing Socket.IO namespaces or connection pooling in a client-server architecture (like the MongoDB collection socket system in the log-viewer-webui), coordinated changes are needed on both client and server sides, making it appropriate to track as a TODO rather than implement piecemeal.
Learnt from: junhaoliao
PR: y-scope/clp#939
File: components/package-template/src/etc/clp-config.yml:64-64
Timestamp: 2025-06-22T04:01:43.409Z
Learning: The new webui architecture uses Fastify with Pino logging instead of the previous Winston-based logging system that was removed during the webui refactoring.
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:27-31
Timestamp: 2025-05-09T19:15:26.180Z
Learning: For the MongoDB real-time updates implementation in components/log-viewer-webui/client/src/api/socket, a socket singleton pattern is used where a single shared socket connection is maintained rather than creating multiple connections. The socket lifecycle is managed centrally, with unsubscription handling in the useCursor React hook's cleanup function.
components/webui/server/src/plugins/MongoSocketIoServer/index.ts (4)
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:32-38
Timestamp: 2025-05-09T18:05:42.814Z
Learning: When implementing Socket.IO namespaces or connection pooling in a client-server architecture (like the MongoDB collection socket system in the log-viewer-webui), coordinated changes are needed on both client and server sides, making it appropriate to track as a TODO rather than implement piecemeal.
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:27-31
Timestamp: 2025-05-09T19:15:26.180Z
Learning: For the MongoDB real-time updates implementation in components/log-viewer-webui/client/src/api/socket, a socket singleton pattern is used where a single shared socket connection is maintained rather than creating multiple connections. The socket lifecycle is managed centrally, with unsubscription handling in the useCursor React hook's cleanup function.
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
Learnt from: junhaoliao
PR: y-scope/clp#899
File: components/log-viewer-webui/server/src/main.ts:50-58
Timestamp: 2025-05-13T19:38:31.164Z
Learning: When using Fastify's `app.close()` method, always wrap it in a try/catch block to properly handle shutdown errors. The close() method returns a Promise that can reject if errors occur during the shutdown process (especially with plugins using onClose hooks), and unhandled rejections could cause the application to hang.
🪛 Biome (1.9.4)
components/webui/server/src/plugins/MongoSocketIoServer/index.ts

[error] 106-108: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: lint-check (ubuntu-latest)
  • GitHub Check: lint-check (macos-latest)

Comment on lines +105 to +108
fastify.log.warn(
`Multiple addresses found for ${fastify.config.HOST}: ${
JSON.stringify(addresses)}. ` +
"Proxying all socket.io requests to the main server."
Copy link
Contributor

@coderabbitai coderabbitai bot Jul 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Use a single template literal – current string concatenation violates style guide

Static analysis is flagging the fastify.log.warn message for concatenation. Switching to one template literal keeps the linter happy and is more readable.

-                fastify.log.warn(
-                    `Multiple addresses found for ${fastify.config.HOST}: ${
-                        JSON.stringify(addresses)}. ` +
-                    "Proxying all socket.io requests to the main server."
-                );
+                fastify.log.warn(
+                    `Multiple addresses found for ${fastify.config.HOST}: ${JSON.stringify(addresses)}. `
+                    + "Proxying all socket.io requests to the main server."
+                );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fastify.log.warn(
`Multiple addresses found for ${fastify.config.HOST}: ${
JSON.stringify(addresses)}. ` +
"Proxying all socket.io requests to the main server."
fastify.log.warn(
`Multiple addresses found for ${fastify.config.HOST}: ${JSON.stringify(addresses)}. `
+ "Proxying all socket.io requests to the main server."
);
🧰 Tools
🪛 Biome (1.9.4)

[error] 106-108: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

🤖 Prompt for AI Agents
In components/webui/server/src/plugins/MongoSocketIoServer/index.ts around lines
105 to 108, the log message uses string concatenation which violates the style
guide. Replace the concatenation with a single template literal that includes
all parts of the message inside backticks to improve readability and satisfy the
linter.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it was broken down to avoid line length violation of max 100 characters

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@junhaoliao I understand - you're balancing the template literal preference with the 100-character line limit. Here's a solution that satisfies both constraints using a multi-line template literal:

fastify.log.warn(
    `Multiple addresses found for ${fastify.config.HOST}: ${JSON.stringify(addresses)}. ` +
    `Proxying all socket.io requests to the main server.`
);

This keeps each line under 100 characters while using template literals throughout, which should satisfy both the linter and the line length constraint.


✏️ Learnings added
Learnt from: junhaoliao
PR: y-scope/clp#1078
File: components/webui/server/src/plugins/MongoSocketIoServer/index.ts:105-108
Timestamp: 2025-07-08T17:20:01.662Z
Learning: The y-scope/clp codebase has a 100-character line length limit that takes precedence over other style preferences like template literals when they conflict.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:32-38
Timestamp: 2025-05-09T18:05:42.814Z
Learning: When implementing Socket.IO namespaces or connection pooling in a client-server architecture (like the MongoDB collection socket system in the log-viewer-webui), coordinated changes are needed on both client and server sides, making it appropriate to track as a TODO rather than implement piecemeal.

Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:27-31
Timestamp: 2025-05-09T19:15:26.180Z
Learning: For the MongoDB real-time updates implementation in components/log-viewer-webui/client/src/api/socket, a socket singleton pattern is used where a single shared socket connection is maintained rather than creating multiple connections. The socket lifecycle is managed centrally, with unsubscription handling in the useCursor React hook's cleanup function.

Learnt from: junhaoliao
PR: y-scope/clp#899
File: components/log-viewer-webui/server/src/main.ts:50-58
Timestamp: 2025-05-13T19:38:31.164Z
Learning: When using Fastify's `app.close()` method, always wrap it in a try/catch block to properly handle shutdown errors. The close() method returns a Promise that can reject if errors occur during the shutdown process (especially with plugins using onClose hooks), and unhandled rejections could cause the application to hang.

@junhaoliao
Copy link
Member Author

I can't test this since mac (maybe @haiqi96), but from what you described the approach makes sense. Do we need this fix for the release?

Hey @haiqi96 , could you confirm this is tested on your WSL + Docker Desktop setup?


Due to the nature of the issue (i.e., Fastify listens on all addresses when localhost can be resolved into multiple ones), I believe it's also possible to test on Mac / Linux by:

  1. Edit /etc/hosts to allow localhost to resolve to both 127.0.0.1 and ::1. e.g.,
    127.0.0.1 localhost
    ::1 localhost
    
  2. Start the fastify server
  3. Access http://127.0.0.1/search and perform a search; observe the search does not hang.
  4. Access http://[::1]/search and perform a search; observe the search does not hang.

@haiqi96
Copy link
Contributor

haiqi96 commented Jul 8, 2025

I can't test this since mac (maybe @haiqi96), but from what you described the approach makes sense. Do we need this fix for the release?

Hey @haiqi96 , could you confirm this is tested on your WSL + Docker Desktop setup?

Due to the nature of the issue (i.e., Fastify listens on all addresses when localhost can be resolved into multiple ones), I believe it's also possible to test on Mac / Linux by:

  1. Edit /etc/hosts to allow localhost to resolve to both 127.0.0.1 and ::1. e.g.,
    127.0.0.1 localhost
    ::1 localhost
    
  2. Start the fastify server
  3. Access http://127.0.0.1/search and perform a search; observe the search does not hang.
  4. Access http://[::1]/search and perform a search; observe the search does not hang.

Yes I have tested it in the morning.

@junhaoliao junhaoliao requested a review from davemarco July 8, 2025 21:21
@davemarco
Copy link
Contributor

davemarco commented Jul 9, 2025

I tested this on linux, and confirmed does not break anything. If required, this can be merged. I am discussing an alternate approach with junhao. The alternate approach is slightly worse but does not require a new dependency or unelegant code (style is good, but it inevitably it would look strange to a new dev on project) . currently weighing options, but this can be merged and we can decide later as well.

@junhaoliao junhaoliao requested a review from davemarco July 9, 2025 19:28
@junhaoliao
Copy link
Member Author

@coderabbitai open an issue about making the socket.io transport (e.g., ws only, polling only, or both) configurable in clp-config.yml

Copy link
Contributor

coderabbitai bot commented Jul 9, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

@junhaoliao I'll create a GitHub issue for making socket.io transport configurable in clp-config.yml.


🏁 Script executed:

#!/bin/bash
# Create a GitHub issue for socket.io transport configuration
gh issue create \
  --title "feat: Make socket.io transport configurable in clp-config.yml" \
  --body "## Description

Allow users to configure socket.io transport methods (websocket only, polling only, or both) through the \`clp-config.yml\` configuration file.

## Background

Currently, socket.io uses the default transport configuration. Making this configurable would allow users to:
- Optimize performance for their specific environment
- Work around network restrictions that might block certain transport methods
- Troubleshoot connectivity issues more effectively

## Proposed Configuration

Add a new configuration option in \`clp-config.yml\` to specify the allowed transport methods:

\`\`\`yaml
webui:
  socket_io:
    transport: \"ws\"  # Options: \"ws\", \"polling\", \"both\"
\`\`\`

## Related

- Pull Request: https://github.com/y-scope/clp/pull/1078
- Comment: https://github.com/y-scope/clp/pull/1078#issuecomment-$(gh pr view 1078 --json comments --jq '.comments[-1].id')

Requested by: @junhaoliao" \
  --assignee junhaoliao

Length of output: 1082


Perfect! I've successfully created the GitHub issue for making socket.io transport configurable in clp-config.yml.

Issue created: #1092

The issue includes:

  • A clear description of the feature request
  • Background context about the benefits of configurable transport methods
  • A proposed configuration format for clp-config.yml
  • References to this PR and your comment
  • Assignment to you as requested

The issue is now ready for discussion and future implementation.


🧠 Learnings used
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:32-38
Timestamp: 2025-05-09T18:05:42.814Z
Learning: When implementing Socket.IO namespaces or connection pooling in a client-server architecture (like the MongoDB collection socket system in the log-viewer-webui), coordinated changes are needed on both client and server sides, making it appropriate to track as a TODO rather than implement piecemeal.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
components/webui/server/src/plugins/MongoSocketIoServer/index.ts (1)

115-118: Proxy still risks infinite recursion and drops WebSocket upgrades

The proxy targets ${fastify.config.HOST}:${fastify.config.PORT} – i.e. the very same server that just registered the proxy – so every /socket.io/ request re-enters the proxy and loops forever.
Additionally, @fastify/http-proxy only forwards WebSocket upgrade requests when websocket: true is supplied; missing this flag breaks Socket.IO on WS transport.

-                fastify.register(fastifyHttpProxy, {
-                    upstream: `${protocol}://${fastify.config.HOST}:${fastify.config.PORT}/socket.io/`,
-                    prefix: "/socket.io/",
-                });
+                fastify.register(fastifyHttpProxy, {
+                    // Route to the primary resolved address to avoid self-proxying
+                    upstream: `${protocol}://${addresses[0].address}:${fastify.config.PORT}`,
+                    prefix: "/socket.io/",
+                    websocket: true, // essential for Socket.IO upgrades
+                });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4bb266b and 2bd7696.

📒 Files selected for processing (1)
  • components/webui/server/src/plugins/MongoSocketIoServer/index.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}`: - Prefer `false == ` rather than `!`.

**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}: - Prefer false == <expression> rather than !<expression>.

⚙️ Source: CodeRabbit Configuration File

List of files the instruction was applied to:

  • components/webui/server/src/plugins/MongoSocketIoServer/index.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:32-38
Timestamp: 2025-05-09T18:05:42.814Z
Learning: When implementing Socket.IO namespaces or connection pooling in a client-server architecture (like the MongoDB collection socket system in the log-viewer-webui), coordinated changes are needed on both client and server sides, making it appropriate to track as a TODO rather than implement piecemeal.
Learnt from: junhaoliao
PR: y-scope/clp#939
File: components/package-template/src/etc/clp-config.yml:64-64
Timestamp: 2025-06-22T04:01:43.409Z
Learning: The new webui architecture uses Fastify with Pino logging instead of the previous Winston-based logging system that was removed during the webui refactoring.
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:27-31
Timestamp: 2025-05-09T19:15:26.180Z
Learning: For the MongoDB real-time updates implementation in components/log-viewer-webui/client/src/api/socket, a socket singleton pattern is used where a single shared socket connection is maintained rather than creating multiple connections. The socket lifecycle is managed centrally, with unsubscription handling in the useCursor React hook's cleanup function.
components/webui/server/src/plugins/MongoSocketIoServer/index.ts (6)
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:32-38
Timestamp: 2025-05-09T18:05:42.814Z
Learning: When implementing Socket.IO namespaces or connection pooling in a client-server architecture (like the MongoDB collection socket system in the log-viewer-webui), coordinated changes are needed on both client and server sides, making it appropriate to track as a TODO rather than implement piecemeal.
Learnt from: davemarco
PR: y-scope/clp#892
File: components/log-viewer-webui/client/src/api/socket/MongoCollectionSocket.ts:27-31
Timestamp: 2025-05-09T19:15:26.180Z
Learning: For the MongoDB real-time updates implementation in components/log-viewer-webui/client/src/api/socket, a socket singleton pattern is used where a single shared socket connection is maintained rather than creating multiple connections. The socket lifecycle is managed centrally, with unsubscription handling in the useCursor React hook's cleanup function.
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
Learnt from: junhaoliao
PR: y-scope/clp#899
File: components/log-viewer-webui/server/src/main.ts:50-58
Timestamp: 2025-05-13T19:38:31.164Z
Learning: When using Fastify's `app.close()` method, always wrap it in a try/catch block to properly handle shutdown errors. The close() method returns a Promise that can reject if errors occur during the shutdown process (especially with plugins using onClose hooks), and unhandled rejections could cause the application to hang.
Learnt from: junhaoliao
PR: y-scope/clp#1078
File: components/webui/server/src/plugins/MongoSocketIoServer/index.ts:105-108
Timestamp: 2025-07-08T17:20:02.560Z
Learning: The y-scope/clp codebase has a 100-character line length limit that takes precedence over other style preferences like template literals when they conflict.
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:35-41
Timestamp: 2024-11-19T19:52:43.429Z
Learning: For internal APIs in `components/log-viewer-webui/client/src/api/query.js`, runtime validation of parameters may not be necessary since the APIs are not exposed to end users, and JsDoc type annotations may be sufficient.
🪛 Biome (1.9.4)
components/webui/server/src/plugins/MongoSocketIoServer/index.ts

[error] 106-108: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: lint-check (ubuntu-latest)
  • GitHub Check: lint-check (macos-latest)

Comment on lines +105 to +108
fastify.log.warn(
`Multiple addresses found for ${fastify.config.HOST}: ${
JSON.stringify(addresses)}. ` +
"Proxying all socket.io requests to the main server."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Use a multiline template literal to satisfy both the linter and ≤100-char line limit

-                fastify.log.warn(
-                    `Multiple addresses found for ${fastify.config.HOST}: ${
-                        JSON.stringify(addresses)}. ` +
-                    "Proxying all socket.io requests to the main server."
-                );
+                fastify.log.warn(
+                    `Multiple addresses found for ${fastify.config.HOST}: ${
+                        JSON.stringify(addresses)
+                    }. Proxying all socket.io requests to the main server.`
+                );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fastify.log.warn(
`Multiple addresses found for ${fastify.config.HOST}: ${
JSON.stringify(addresses)}. ` +
"Proxying all socket.io requests to the main server."
fastify.log.warn(
`Multiple addresses found for ${fastify.config.HOST}: ${
JSON.stringify(addresses)
}. Proxying all socket.io requests to the main server.`
);
🧰 Tools
🪛 Biome (1.9.4)

[error] 106-108: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)

🤖 Prompt for AI Agents
In components/webui/server/src/plugins/MongoSocketIoServer/index.ts around lines
105 to 108, the current log statement concatenates strings and exceeds the
100-character line limit, which violates the linter rules. Refactor the log
message to use a multiline template literal instead of string concatenation,
breaking the message into multiple lines within backticks to satisfy both the
linter and line length constraints.

@junhaoliao
Copy link
Member Author

I tested this on linux, and confirmed does not break anything. If required, this can be merged. I am discussing an alternate approach with junhao. The alternate approach is slightly worse but does not require a new dependency or unelegant code (style is good, but it inevitably it would look strange to a new dev on project) . currently weighing options, but this can be merged and we can decide later as well.

@davemarco the rabbit has helped to create an issue at #1092 about the transport config option we discussed offline. I believe it will be a good opportunity to revisit the changes in the current PR when we implement #1092 .

Copy link
Contributor

@davemarco davemarco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am okay with this. But when we come back to issue #1092 later on, we should consider removing this code and forcing socket io to try attempt websocket connection first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants