0

I'm using worker_threads in nodejs to read multiple files and process the rows to later insert into the database (using oracle-db).

Aproximately i work with more than one million rows and every file have more than 10,000 rows.

when i was trying to create the "binds" to insert into the database of every row field, while using forEachAsyncParallel or promises of every row in .map i got the following error:

Error

RangeError: Value undefined out of range for undefined options property undefined
    at Set.add (<anonymous>)
    at AsyncHook.init (internal/inspector_async_hook.js:23:25)
    at PromiseWrap.emitInitNative (internal/async_hooks.js:182:43)
    at /app/services/workers/PushMultiValueFile.worker.js:1:1
    at new Promise (<anonymous>)
    at /app/services/workers/PushMultiValueFile.worker.js:20:84
    at Array.map (<anonymous>)
    at /app/services/workers/PushMultiValueFile.worker.js:20:57
    at new Promise (<anonymous>)
    at AssignKeysNameOnValues (/app/services/workers/PushMultiValueFile.worker.js:16:12)
RangeError: Value undefined out of range for undefined options property undefined
    at Set.add (<anonymous>)
    at AsyncHook.init (internal/inspector_async_hook.js:23:25)
    at PromiseWrap.emitInitNative (internal/async_hooks.js:182:43)
    at Promise.then (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)

-----------------------

***Custom code to read error:***
[2021-03-10T19:34:47.331Z] 
{
  captured_at: 2021-03-10T19:34:47.000Z,
  messages: '"Error: Worker stopped with exit code 1"',
  stacktrace: '"Error: Error: Worker stopped with exit code 1\\n    at /app/services/oracle_database.js:434:36\\n    at processTicksAndRejections (internal/process/task_queues.js:97:5)"',
  execution_detail_id: 1203
}

There is a way to find fix this?

Map with Promises

function AssignKeysNameOnValues(keys, values) {
    return new Promise( async (resolve, reject) => {
        try {
            let result = {};
            if (Object.entries(keys).length > 0) {
                const promises = (Object.entries(keys)).map( async (item,index) => new Promise( async (resolve, reject) => {
                    try{
                        if ([(oracledb.DB_TYPE_NUMBER)].includes(item[1].type))  {
                            result[item[0]] = values[index] ? parseFloat(values[index]) : null;
                            resolve()
                        }
                        else {
                            result[item[0]] = values[index];
                            resolve()
                        }
                    } catch (e) {
                        // throw await logError(new Error(error),(workerData.executionID));
                        reject();
                    }
                  }));

                  Promise.all(promises)
                    .then(() => {
                      resolve(result);
                    })
                    .catch((err) => {
                      reject(err);
                    });
            }
            else {
                resolve();
            }
        } catch (err) {
            reject(err);
        }
    });
}

The parameters receive:

Keys:

{
  ARRANGEMENT_ID: {
    type: 2001,
    maxSize: 255,
  },
  OWNER: {
    type: 2001,
    maxSize: 255,
  },
  LINKED_APPL: {
    type: 2001,
    maxSize: 255,
  }
}

Values:

{
  "0": "ARR16@#$%3423C0",
  "1": "1",
  "2": "42"
}

Other type to iterate the same values but i got the same error.

forEachAsyncParallel

Array.prototype.forEachAsyncParallel = async function (fn) {
    await Promise.all(this.map(fn));
}

Versions:

  • Node: v12.18.4
  • Npm: 6.14.6
Emilio
  • 3
  • 3
  • How are you calling the function? what data use for arguments? – Clystian Mar 10 '21 at 19:56
  • @Clystian, i just call the function sending the parameters, the first one "keys" store the fields and their data type. And the second "values" store the field value. In that function i only want to match the field with their respective field value. i update the question, look above. – Emilio Mar 10 '21 at 21:05
  • A side comment about your goal: for performance make sure you are using `executeMany()`. See [Batch Statement Execution and Bulk Loading](https://oracle.github.io/node-oracledb/doc/api.html#batchexecution). I assume you are using node-oracledb. – Christopher Jones Mar 10 '21 at 22:18
  • @ChristopherJones sure ! I'm using `executeMany()` after I build all the binds of records. thanks. And yes, I'm using `node-oracledb` – Emilio Mar 10 '21 at 22:20

1 Answers1

0
RangeError: Value undefined out of range for undefined options property undefined

The above error is caused when a Set or Map hitting the maximum limit of elements. See reference: Maximum number of entries in Node.js Map?

If still run into the problem, you can try large-set and large-map, a package that allows you to store and handle a large number of elements without worrying about the 16.777.216 (2^24) limit in a Set or Map by partitions into smaller, enabling it to store and access more elements than the built-in Set or Map.