1

I have the fallowing problem: I have a backend in php on the codeigniter framework where I will get weight data from a weigher machine that is send from a external C# application(cannot modify that C# app). I will get the weight data each time weigher will update the value, so for example it will start from 0, 100, 300, 400, 1000, 1500, 600, 400, 300, 100, and back to 0 (it will get down when the product is off the scale), and all this values are generated one entry at a second, so I will have them fast, and insert that on my mysql database with this function:

public function balance() {
    $evType = $this->input->post('eventType');
    $weight = $this->input->post('balanceWeight');

    if ($evType !== false && $weight !== false) {
        $evType = intval($evType);
        $weight = intval($weight);


        switch($this->balance_events->insert($evType, $weight)) {
            case OpResult::Ok;
                $this->_issue_success();
                    if($weight>100){
                    $insert_id = $this->db->insert_id();
                    $this->Curlsynologyapi->CURLsaveimage($insert_id);
                    }            
                break;
            case OpResult::InvalidParameters;
                $this->_issue_respond_with_reason("Not all parameters were supplied.", HttpResponse::BadRequest);
                break;
            case OpResult::Failed:
                $this->_issue_respond_with_reason("Internal server error occured while inserting the balance entry. Please try again ...", HttpResponse::InternalServerError);
                break;
            default:
                break;
        }
    }
}

So to exaplain this fast, $weight will hold the weight value (ignore the $evType, that is some scale eveniment). And that will have to hold and insert data fast as new values will come. Now I will have a condition: if($weight>100) when that is TRUE I go to another function that I will list above, what that does is to make a camera print screen and save that image to my server on a chosen folder and name it with the id of weight value that was inserted on mysql. This is what I call that after my if statement is true:

public function CURLsaveimage($insert_id) {
   $datasidget = $this->curl->simple_get('blablabla this is my api login url');
   $datasid = json_decode($datasidget,true);
   $data_sid =  $datasid['data']['sid'];

   $reqUrl = "blabla this is my print screen from a live camera api url";
   $imageencode = $this->curl->simple_get($reqUrl);
   $path = "./images/$insert_id";
   write_file($path, $imageencode, $mode = 'wb');

}

The execution of the api requests from my last function will take like 30-40 sec and that is to much compared with the speed I will get weight values (1 entry/sec). And when the if will trigger and start the api requests I will miss all the weight data until the requests are done. Thing is that I can afford to get 1 print screen per scale session (that means when someone will put something on the scale, I need to do 1 print screen when the condition is triggered, and then wait to the next weighting event, weigher machine wont generate non-stop data, but when it generates I have to get it fast).

What I was thinking is something to make the request to api process in parallel so that the flow of the weight events isn't affected and when the api request is done start again to check when if will get true and so on, I would also like if I can have some control of that parallel process to use some sleep with it or something.

I read a bit about php workers and threads, I saw redis, german, heroku, but to be honest they seem to be a bit hard to understand and documentation is quite thin for that and I also I think they are too much for my problem.

Question is there anything around lightweight and approachable for someone that is not that advanced in php?

Thank you so much for your time!

Bogdan
  • 243
  • 3
  • 20

1 Answers1

1

Yes, you can make a simple queue of tasks by yourself.

Every time you need to request API, you will create a task, and store it in your database in some custom table, where only tasks are stored. Because we are only saving task to database and not making api requests here, it is fast.

Now we have a queue(a table in database) with tasks to complete, so now we need some php worker to get one task from queue and execute it.

Create a simple php script, that will get one task from database(like "select * from tasks limit 1"), executes it, and then deletes this task from database upon completion (or it can change a status of task).

Now we have only one problem, who will run this script and when? We can use cron for this. We can schedule to run our script every minute for example.

php script can be run every minutes by cron for example.

And your code will be looked like this:

       switch($this->balance_events->insert($evType, $weight)) {
            case OpResult::Ok;
                $this->_issue_success();
                    if($weight>100){
                        $insert_id = $this->db->insert_id();
                        $saveCameraImageTask = new SaveCameraImageTask($insert_id);
                        $saveCameraImageTask->save()//save it to database, we are just saving it to our database, no api request, so it is fast.
                    }            
                break;
            case OpResult::InvalidParameters;
                $this->_issue_respond_with_reason("Not all parameters were supplied.", HttpResponse::BadRequest);
                break;
            case OpResult::Failed:
                $this->_issue_respond_with_reason("Internal server error occured while inserting the balance entry. Please try again ...", HttpResponse::InternalServerError);
                break;
            default:
                break;
        }
Clickbeetle
  • 629
  • 4
  • 13
  • Hmm, that is interesting, thanks for your reply, my question is that since the actual print screens that I do are from a live camera and I want to process as fast as the task will get in my db (cause I want to make the camera picture printscreen at as close in time as the if triggers, want to check what product (on the scale) is there ). For example, there is a possibility to start the task from my database as soon as the task is inserted there ? – Bogdan Feb 16 '17 at 11:56
  • Well it depends. If you want to run task on trigger, when a new row inserted, there is no easy solution, as far as i know. Similar question was here http://stackoverflow.com/questions/21019886/how-to-check-in-real-time-if-new-row-was-added-to-mysql-table However if you want to check for new row more often than 1 minute, you can do it. – Clickbeetle Feb 16 '17 at 12:24
  • My solution is more suitable, when you have some task, which you want to run soon, but not at the same moment. If you need instant simultaneous execution, then you really need gearman, rabbit and etc. – Clickbeetle Feb 16 '17 at 12:33