joltup / react-native-threads

Create new JS processes for CPU intensive work
MIT License
756 stars 142 forks source link

How to shut down the thread after a predefined timeout and re-lance it ? #83

Open ChenhuaWANG22 opened 5 years ago

ChenhuaWANG22 commented 5 years ago

Update Time: 2019-Oct-03 Update Title: How to shut down the thread after a predefined timeout and re-lance it ? After further researching and diagnosis, it turns out it's the linear programming solver which will cause the javascript freeze or infinite loop (as this solver will be called around 2e6 times, the very small possibility of freezing becomes almost certain after given iterations).

So, the question now becomes: How to shut down the thread after a predefined timeout and re-lance it ?

Besides, during the diagnosis process, it is worthy to mention the diagnosis method: moving the code to the main thread and use "console.log" can get real-time log information(at least with the current React Native Debugger, I am using react-native 0.57.1) which will help a lot to find out where the code is running currently and where it is stuck (as Reactotron won't provide log in real time as the originally post mentioned below).

Below is an example.

        console.log(`solver start ${counter}`);
        console.log(JSON.stringify(modelLP));
        resultLP = solver.Solve(modelLP);
        console.log(`solver return ${counter}`); 

Original Post Time: 2019-Oct-03 Original Title: frequent no response from thread

Normally the thread in my project should send message after around 39 seconds of execution or longer (in case of more iterations). However, frequently the thread just keeps silence neither sends back message nor occurs an error. This makes the debug process like guessing a riddle.

I have also used Reactotron to log inside the thread. The log is shown below. However, it's not real time updated and all logs are shown at the end. For example, the log with time 1:07:35 is not shown really at 1:07:35 while it's shown at around 1:07:47 with the rest of other logs. Thus, this method is not helpful to know the status of current thread (running correctly or something goes wrong) or to know where the code is executed currently or to know which part of the code goes wrong.

So, the question is:

  1. is this a bug or do I mistake something ?
  2. is there any good way to know which part of the code is executed currently?

image

below is the code example in my project:

inside a screen:

// on top
var workerThread = null;

// in render() function of one screen class
// onPress is part of a button component

                  onPress: () => {

                    const json = JSON.stringify(dataObject);

                    workerThread = new Thread('threads/thread.js');
                    // send a message, strings only
                    workerThread.postMessage(json);

                    // listen for messages
                    workerThread.onmessage = (message) => {

                      // store result
                      funcNavigationUpdate({
                        [NAVIGATION_ATTRIBUTES.TEMP]: message
                      });

                      // stop the JS process
                      workerThread.terminate();
                      workerThread = null;

                    navigate('Plans', {});
                  },

In side threads/thread.js':

self.onmessage = (message) => {

    console.tron.log(`THREAD: start`);

    const data = JSON.parse(message);

    const {
        array,
        calculatedData
    } = data;

    let i;
    for (i = 0; i < array.length; i++) {
        // do something heavy here
        heavyWork1();

        console.tron.log(`THREAD: ${i}`);
    };

    // do something heavy here
    const r = heavyWork2();

    console.tron.log(`THREAD: end week`);

    self.postMessage(JSON.stringify(r));
}

package.json"

{
   "dependencies": {
      "javascript-lp-solver": "0.4.5",
      "react": "16.5.0",
      "react-native": "0.57.1",
      "react-native-console-time-polyfill": "1.2.1",
      "react-native-gesture-handler": "1.0.17",
      "react-native-modal": "7.0.2",
      "react-native-modal-datetime-picker": "6.0.0",
      "react-native-reanimated": "1.0.0-alpha.11",
      "react-native-threads": "0.0.15",
      "react-native-vector-icons": "6.6.0",
      "react-navigation": "3.0.9",
      "react-redux": "6.0.0",
      "redux": "4.0.1",
      "redux-logger": "3.0.6",
      "redux-offline": "2.0.0",
      "redux-thunk": "2.3.0",
      "uuid": "3.3.2"
   },
   "devDependencies": {
      "babel-jest": "24.9.0",
      "jest": "24.9.0",
      "metro-react-native-babel-preset": "0.56.0",
      "react-test-renderer": "16.5.0",
      "reactotron-react-native": "3.6.4",
      "reactotron-redux": "2.1.3"
   },
   "jest": {
      "preset": "react-native"
   }
}