0

Basically, no matter what I do any array made from a buffer (doesn't have to be shared) results in an array the same length of elements as the buffer, but all of its values are zero. Note I need to do this in chrome and the Mozilla docs on typed arrays don't seem to hold for chrome.

I want an array representing a buffer that already has data in it. My use case is a webworker receiving a shared array buffer that already has data in it. However, I am not successful in creating a view that represents that buffer.

function testIntBuffer(n) {
    return new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * n);
}

function fillIntBuffer(buffer, endInt) {
    for (var i = 0; i <= endInt; i++) {
        buffer[i] = i;
    }
    return buffer;
}

var a = testIntBuffer(10);
fillIntBuffer(a, 10);
console.log(a);

var b = new Int32Array(a);
console.log(b)

This is what the real code in my project looks like (aside from the fake data function):

//inside main.js
function fakeDataArray(n) {
    const arr = [];
    for(let i = 0; i <= n; i++) {
        arr[i] = Math.floor(Math.random() * 100);
    }
    return arr;
}

function normalArrayToSBA(rawData) {
    const n = rawData.length;
    const m = Int32Array.BYTES_PER_ELEMENT;
    const data = new SharedArrayBuffer(m * n);
    rawData.forEach((datum, i) => {
        data[i] = datum;
    });
    return [data, n, m];
}

function createWorker() {
        const w = new Worker('workerBundle.js');
        w.onmessage = (event) => {
            const command = event.data.command;
            if (command === 'workerFinish') {
                console.log('event recieved from worker: ', event);
            }
            if (!command) {
                return;
            }
        };
        return w;
    }

function startworker(dataInfo, options) {
    const worker = createWorker();
    function setWorkerData(dataInfo) {
        const priceBuffer = dataInfo[0];
        const size = dataInfo[1];
        const offset = dataInfo[2];
        worker.postMessage({
            command: 'setData',
            priceBuffer: priceBuffer,
            size: size,
            offset: offset
        });
    }
    function getWorkerStats(_options) {
        worker.postMessage({
            command: 'getStats',
            options: _options,
        });
    }
    const id = Math.random();
    setWorkerData(dataInfo);
    getWorkerStats(options);
}

let data = fakeDataArray(5751);
let dataInfo = normalArrayToSBA(data);
startworker(dataInfo);

//inside workerBundle.js

//eslint-disable-next-line no-unused-vars
const WorkerMessageInterface = {
    file: null,
    priceData: null,
    role: 'worker',
    id: null,
    pendingRequests: {},
    setRole(event) {
        WorkerMessageInterface.role = event.data.role;
        WorkerMessageInterface.id = event.data.id;
        self.postMessage({
            success: true,
            commandGiven: event.data.command
        });
    },
    //command: 'setFile'
    /*{ command: 'setFile', fileInfo: String }*/
    setFile(event) {
        WorkerMessageInterface.file = event.data.file;
        self.postMessage({
            success: true,
            commandGiven: event.data.command
        });
    },
    //command: 'setData'
    /**
     * @param {priceData} Array
     * @param {source} String - Indicates what utility mapping  is necesarry
     *                          to convert data into the highcharts format
    */
    setData(event) {
        const data = event.data;
        const priceBuffer = new Int32Array(data.priceBuffer);
        WorkerMessageInterface.priceData = [priceBuffer, data.size];
    },
    //command: 'getSignals'
    /**
     * @param {options} Object
    */
    getAverage(dataArray) {
        let sum = 0;
        let length = dataArray.length;
        dataArray.forEach((n) => {
            sum += n;
        });
        return sum / length;
    },
    getStats(event) {
        const ops = event.data.options;
        const id = WorkerMessageInterface.id;
        const data = WorkerMessageInterface.priceData;
        const stats = WorkerMessageInterface.getAverage(data);
        if (WorkerMessageInterface.role === 'worker') {
            self.postMessage({
                results: stats,
                command: 'workerFinish',
                id: id
            });
        }
    },
    listenForCommands() {
        self.onmessage = (event) => {
            const command = event.data.command;
            WorkerMessageInterface[command](event);
            self.postMessage({
                worker: true,
                commandGiven: command,
                status: 'recieved',
            });
        };
    }
};
WorkerMessageInterface.listenForCommands();

1 Answer 1

1

Pass SharedArrayBuffer to new Int32Array() before calling fillIntBuffer()

function testIntBuffer(n) {
  return new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * n);
}

function fillIntBuffer(buffer, endInt) {
  for (var i = 0; i <= endInt; i++) {
    buffer[i] = i;
  }
  return buffer;
}

var a = testIntBuffer(10);
var b = new Int32Array(a);
fillIntBuffer(b, 10);
console.log(b);

Sign up to request clarification or add additional context in comments.

9 Comments

I'm sorry if it wasn't clear in my question, I want an array representing a buffer that already has data in it. My use case is a webworker receiving a shared array buffer that already has data in it. However, I am not successful in creating a view that represents that buffer.
What do you mean by "already has data in it"? The data is set within the Int32Array at Answer, following pattern at Question. How do you pass the ArrayBuffer to Worker? Can you include the actual code and use case description at Question? See stackoverflow.com/help/how-to-ask, stackoverflow.com/help/mcve.
An ArrayBuffer itself cannot be filled with values. A TypedArray can have values set. "I am sending the buffer to the webworker via post message." Yes, though how? At which parameter? Yes, the code itself, included at the Question, would probably be helpful towards resolving inquiry.
Are you referencing an Array or an ArrayBuffer? What are you trying to achieve? What is input and expected result? Have you the read links posted at previous comment stackoverflow.com/questions/46557283/…?
Use the same approach at Worker thread. let ab = new Int32Array(event.data); for (let i = 0; i < ab.length; i++) { // do stuff with ab[i]}
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.