summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2024-03-06 20:07:41 -0300
committerEuAndreh <eu@euandre.org>2024-03-06 20:18:05 -0300
commit40118a188fb05219d1188ff775ce71f66c8cb56a (patch)
tree85d4f39c5b3bb9b0bf342bf9b3e364c21fd16be6
parentsrc/hero.mjs: Change server.listen() to receive no arguments (diff)
downloadpapod-40118a188fb05219d1188ff775ce71f66c8cb56a.tar.gz
papod-40118a188fb05219d1188ff775ce71f66c8cb56a.tar.xz
src/hero.mjs: Add simplified implementation of `makePipeReader()`
There are a few limitations of the current approach that I didn't figure out how to solve yet: 1. when stopping the server, mainly for shutting down the Node.js process when running the tests, we need to open and close the pipe in write mode at least once, otherwise it hangs forever. After opening and closing it, the "autoClose" functionality of the `fs.createReadStream()` kicks in, and it closes, otherwise the test hangs forever as Node.js still has open handles. That's why the `server.close()` function has a gratuitous call to `fs.createWriteStream(pipe).end()`: so that when stopping the server, the pipe is always closed at least once; 2. when actually running the application, if one tries an IPC command like: $ echo '{ "action": "config-dump" }' > web.pipe It works, but only for the first time. As this shell line opened the pipe, wrote to it and then closed it, the reader that `makePipeReader()` constructed closed, but didn't open it again. So when running the exact same IPC command for a second time, the shell hangs, as there is no process on the other side listening for the command and consuming the pipe. Shortcoming nº 2 is much more important to be solved, as we can live with shortcoming nª 1 for some time. Both are to be fixed in the near future.
-rw-r--r--src/hero.mjs7
-rw-r--r--tests/js/hero.mjs21
2 files changed, 26 insertions, 2 deletions
diff --git a/src/hero.mjs b/src/hero.mjs
index 699e426..bcc4fdb 100644
--- a/src/hero.mjs
+++ b/src/hero.mjs
@@ -363,7 +363,7 @@ export const makePipeReaderFn = ({
lineFn: lineHandler
}) => path => {
mkfifo(path);
- // TODO
+ fs.createReadStream(path, "UTF-8").on("data", makeLineEmitter(lineFn));
};
export const makePipeReader = makePipeReaderFn();
@@ -397,7 +397,10 @@ export const promisifyServer = (name, serverHandle, socket, pipe) => ({
rmIf(socket);
return serverHandle.listen(socket, ...args)
}),
- close: util.promisify((...args) => serverHandle.close(...args)),
+ close: util.promisify((...args) => {
+ fs.createWriteStream(pipe).end();
+ return serverHandle.close(...args);
+ }),
events: serverHandle,
});
diff --git a/tests/js/hero.mjs b/tests/js/hero.mjs
index 67cf690..14d9a07 100644
--- a/tests/js/hero.mjs
+++ b/tests/js/hero.mjs
@@ -1378,6 +1378,12 @@ const test_makePipeReaderFn = async t => {
const lines = [];
const lineFn = x => lines.push(x);
const makePipeReader = makePipeReaderFn({ lineFn: null });
+
+ rmIf(path);
+ makePipeReader(path);
+ fs.createWriteStream(path).end();
+
+ assert.deepEqual(lines, []);
});
await t.test("closing on pipe EOF reopens", async () => {
@@ -1385,6 +1391,21 @@ const test_makePipeReaderFn = async t => {
const lines = [];
const lineFn = x => lines.push(x);
const makePipeReader = makePipeReaderFn({ lineFn });
+
+ rmIf(path);
+ makePipeReader(path);
+ const writer = fs.createWriteStream(path);
+ writer.end("first\nsecond\nthird\n");
+ return new Promise((resolve, reject) => {
+ writer.close(() => {
+ assert.deepEqual(lines, [
+ "first",
+ "second",
+ "third",
+ ]);
+ resolve();
+ });
+ });
});
};