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

Cannot exit all the processes when CTRL + C in readline #10403

Open
fzn0x opened this issue Apr 20, 2024 · 2 comments
Open

Cannot exit all the processes when CTRL + C in readline #10403

fzn0x opened this issue Apr 20, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@fzn0x
Copy link
Contributor

fzn0x commented Apr 20, 2024

What version of Bun is running?

1.1.3+2615dc742

What platform is your computer?

Microsoft Windows NT 10.0.22621.0 x64

What steps can reproduce the bug?

  1. I'm using this code to apply 2 ways of SIGINT, process SIGINT and readline SIGINT
// Import the readline module to mock user interactions via the console.
const readline = require('readline');

// Mock the client and its dependencies with basic stubs.
class Client {
    async sendRequest(url: string) {
        return 'Response from ' + url; // Dummy response
    }
}

// Function to simulate response conversion from gemtext.
function fromGemtext(response: string) {
    return response; // Simply return the same dummy response for simplicity
}

const client = new Client();
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

process.on('SIGINT', function () {
    console.log('Graceful shutdown');
    process.exit(0);
}).on('SIGINT', function () {
    process.emit('SIGINT');
});

process.on('SIGINT', function () {
  // graceful shutdown
  process.kill(process.pid, 'SIGINT');
});

// Versioning for the dummy package.
const version = '1.0.0';  // Hardcoded version
console.log(`Dummy Client v${version}`);

console.log("Dummy CLI for testing. Type '/c' to exit or any URL to simulate a request.");

// Function to handle the "gemini" requests in a dummy manner.
async function handleGeminiRequest(inputUrl: string) {
    try {
        const response = await client.sendRequest(inputUrl);
        console.log(fromGemtext(response));
    } catch (err) {
        if (err instanceof Error)
            console.log('Error:', err.message);
    }
}

// Function to create commands.
function createCommands(string: string) {
    if (string.trim() === '/c') {
        return 'exit';
    }
    return 'url-request'; // Default to URL request for any other input
}

// Function to prompt and process commands.
function promptAndProcessCommand() {
    console.log(`Platform ${process.platform}, Node ${process.version}, isTTY? ${process.stdout.isTTY}`);
    if (process.platform === "win32") {
        rl.on("SIGINT", function () {
            console.log("Process terminated (SIGINT).");
            process.kill(process.pid, 'SIGINT');
        });
    }

    rl.question('> ', async (cmd: string) => {
        const command = createCommands(cmd);
        switch (command) {
            case 'exit':
                console.log('Bye!');
                rl.close();
                process.exit(0);
            case 'url-request':
                await handleGeminiRequest(cmd);
                promptAndProcessCommand(); // Continue the command loop
                break;
        }
    });
}

// Start the command loop.
promptAndProcessCommand();
  1. run the code
  2. when > is visible try to press CTRL + C

What is the expected behavior?

When I press CTRL + C it should exit my program gracefully.

What do you see instead?

I need to press Enter after CTRL + C or Enter first to CTRL + C.

Additional information

Related:

@fzn0x fzn0x added the bug Something isn't working label Apr 20, 2024
@fzn0x
Copy link
Contributor Author

fzn0x commented Apr 20, 2024

(possibly related):
#9944
#9853

@fzn0x
Copy link
Contributor Author

fzn0x commented Apr 20, 2024

Temporary solution (for my case) was adding keypress event if the stdin isTTY is true.

import * as readline from "node:readline";

// TODO: remove code when https://github.com/oven-sh/bun/issues/10403 is fixed
if (process.stdin.isTTY) {
  readline.emitKeypressEvents(process.stdin);
  process.stdin.setRawMode(true);

  process.stdin.on("keypress", (str, key) => {
    if (key.ctrl && key.name === "c") process.exit();
  });
}

This simply ignores the defect because whenever ctrl and key c is pressed in the stdin process, it will exit the process.

Note: This would not solve the whole related issues. This behaviour still need to be fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant