0

I'm nub in php, I'm more specialized c++. There my question.

I need to implement such sequence:

  • First process performs some calculations, store it in DB (or file)

  • Second process answer the user requests and pass last calculations results (stored by 1st process).

What the best practices to do this? I assume something like this:

if (!calculatorProcess.running())
{
    calculatorProcess.run([]{
        // do something like this 
        while (1) {
            performCalculations();
            storeSomewhere();
            sleep(1);
        }
    }
}
getLastCalculationResults();
sendResponce();

Thanks in advance

tenta4
  • 304
  • 2
  • 16
  • I'm nub in c++, I'm more specialized php. Here is my comment: *The page won't load if `while (1)`. Also it is too broad to write an answer, you should break the problem into pieces and solve it. Best practises are something that you do when you can write the code fluently. Right now just focus on how to do it, don't jump to best practises directly unless you want to get confused.* – Aniket Sahrawat Mar 25 '18 at 13:27
  • @AniketSahrawat, :) thank you for detailed responce. That is the matter, that I don't want that calculations will be a part of page. Because I want to calculate once for many requests with some time period (let's say every 1 second) – tenta4 Mar 25 '18 at 13:48
  • Sorry but this does not sound logical to me. Or this might be the case where you are failing to express exactly what you are up to. You should write some examples with php and get the fundamentals right. I am sure you will get the answer all by yourself. – Aniket Sahrawat Mar 25 '18 at 14:02

2 Answers2

1

For what it's worth, you're not really supposed to design PHP applications this way. It's theoretically meant to be fully synchronous, since it's supposed to handle HTTP requests, which are fully synchronous themselves.

Given your example, if task 1 is a long-running process, you're eventually going to need task 2 to sleep for some period of time, or poll whatever is controlling task 1 to see if it's finished. In doing so, you run the risk of your HTTP request timing out ifyou don't respond. If you're having to do this, it's better to just do the entire business in one PHP process.

A better way (but not the only way) to handle this, assuming task 1 is a sufficiently long running process that the user would notice, might be to do something like this:

//PHP - longrunningprocess.php
$jobId = generateJobId();

//Actually launch the long-running process.  There are alternatives to exec, such Icicle:
//https://github.com/icicleio/icicle
exec('/path/to/long_running_script.php arg1 arg2 arg3');

echo '{ "jobId":'.$jobId.'}';
//end

//PHP - longrunningprocessresult.php
$jobId  $_GET['jobId'];

var result = new LongRunningProcessResult();

 var jobStatus = getJobStatus();

 if(jobStatus.complete != true)
 {
     result.complete = true;
     result.property1 = jobStatus.property1;
     //...
 }
 else
 {
     result.complete = false;
 }

echo json_encode(result);

And then on the client side, something like this:

function handleJobSuccess(results)
{
    //Do whatever you do with the results
}

function checkForCompletion(jobId)
{
    setTimeout(function() {
        $.ajax("longrunningprocessresult.php?jobId=" + jobId, {success: function(args){
                if(args.success)
                {
                    handleJobSuccess(args);
                }
                else
                {
                    checkForCompletion(jobId);
                }
            }
        });
    }, 5000);
}

function beginLongRunningProcess()
{
    showWorkingThrobber();

    $.ajax('longrunningprocess.php', { success: function(args){
        var jobId = args.jobId;

        checkForCompletion(jobId);

    }});
}

The important takeaway for this being that you don't want to send a request to the server for a long running process that just ties up the browser while it runs. You need to implement a UI that at least implies to the user that the process is working, and then handles the result asynchronously.

Aaron Averett
  • 896
  • 10
  • 12
1

In general you should regard PHP as a scripting language. The same as a bash script on Linux or Power Shell script on Windows. If you have to process your data at regular intervals you can schedule a process.php script to be executed at regular intervals to process data or to be executed by a script which sends the data. query.php should return the processed data, from the DB, when users request the data. So, you don't need two threads or processes but two separate files which will be run by your server (when accessed by the users) or by by PHP on command line (when running as a scheduled task). Hope I got your question right and this answers your question.

EmilCataranciuc
  • 1,024
  • 1
  • 11
  • 24
  • If you found my answer to be what you were looking for then you can mark it as accepted. :-) – EmilCataranciuc Apr 04 '18 at 12:13
  • Okey, my understanding of your answer sounds suitable for me. I have 2 approaches: [1] move calculations in separate calc.php, which will requested by PHP command line at regular intervals (calc.php also updates DB) [2] update calculation results at main user requst, but no more than interval time. `request() { if ((currTime - prevTime) > interval) { recalculate(); } sendResponce(); }` Second approach less suitable because it lead to responces delays in cases when recalculations required. So, thank you for answer) – tenta4 Apr 04 '18 at 12:27
  • The first approach seems the best to me. But it may depend on the details of your implementation. I would appreciate if you would mark my answer as accepted. That if it is indeed. – EmilCataranciuc Apr 04 '18 at 14:27