goodvibration
goodvibration

Reputation: 6206

Can I safely wrap functions using this scheme?

I'd like to wrap several fs functions so that each one of them will retry on error until success.

My purpose is to wrap those functions while leaving the rest of my code completely unchanged.

Here is my scheme:

First, I implement the following file, named fix.js:

const _fs = {};

module.exports = function(fs) {
    for (const funcName of ["readFileSync", "writeFileSync", "appendFileSync"]) {
        _fs[funcName] = fs[funcName];
        fs[funcName] = function(...args) {
            while (true) {
                try {
                    return _fs[funcName](...args);
                }
                catch (error) {
                    console.log(error.message);
                }
            }
        };
    }
};

Then, in my code, immediately after fs = require("fs"), I call require("./fix")(fs).

Is this scheme safer, or should I worry about any sort of undefined behavior?

For example, I am assuming that the _fs object in file fix.js will continue to "live" after the require("./fix") statement is executed, but I'm not so sure that this assumption is correct.

Upvotes: 0

Views: 78

Answers (1)

Fast answer is "Yes, is safe".

Long answer is "Yes, is safe but...". Explaining:

Is safe because it will work as you expect and will not break nothing. Until here, everything is fine.

The problem comes if the error you get is unsalvable until you manually do something. For example a "permissions error". The code will be looping forever until you solve that manually, also maybe clogging CPU or disk I/O, and is impossible to add small delays between retries without eating CPU for free. That's the problem of synchronous functions actually.

If you get the EBUSY problem you talked about in other post, it will eat one entire CPU in the loop and a lot of disk I/O operations until the file is not busy, so there are chances that will slow the operations that the other process is doing to the file. If you only have 1 core, the operations will slow a LOT. Is not optimal. If you have a complex situation, you must avoid sync fs functions. The best you can do now is to use fs non-blocking functions and wait a bit of time before the next check. Waiting a single tick can be really a change in optimization here. You can try to use async and await to keep the inline feeling, without callbacks, but free the event loop and not eat extra CPU and disk I/O.

By the way, those are extra details. In general is safe to wrap fs functions.

Upvotes: 1

Related Questions