Jump to content

Alternative queue system


TrueMember

Recommended Posts

Hi folks,

I'm trying do a system like a queue, but doesn't work like i expected.

OS: Windows (IIS)

PHP: 5.2

So, let me tell you, what i'm doing.

1º Click in one button and insert the entry into database

$stmt = odbc_prepare($conn, 'INSERT INTO queue (ask_date, run_date, executed, user_id) VALUES (GETDATE(), NULL, 0, ?)');

2º After that i will run a script to check values executed = 0

    $handle = new COM('WScript.Shell');
    $handle->Run("php generate.php", 0, false);

3º Check values executed = 0 and update de column executed to 1 (generate.php)

    $sql = "SELECT * FROM queue WHERE executed=0;";
    $rsQueue = odbc_exec($conn, $sql);
    while (odbc_fetch_row($rsQueue )) {
    //code here
    }

My problem is, when i click in button it will open always new process (php.exe). (2 clicks - 2 processes; 3 clicks - 3 processes; etc..)

My ideia is, first button click execute the script (2º) but the other times if script is running, only add the content to queue table to be executed in current process.

Someone have any ideia?

Thank you!

Link to comment
Share on other sites

1 hour ago, gw1500se said:

Can you not have the script check itself? If there is already a copy running, just exit. The PHP script won't know or care either way.

 

How do you think I can do that? I don't got your point.

1 hour ago, kicken said:

Dont launch your second script from the first.  Set it up as a system service (using nssm) or as a scheduled task.

 

Why? I need lunch to execute the task immediately. I can shedule a job, but i need it run at every 5 minutos to check any entry to be executed. (i have another jobs and shouldn't not be a good solution)

 

Thanks all

Link to comment
Share on other sites

When the script starts check for a specific file in, say, \temp. If it is there, exit. If it is not then create the file and proceed. You will need to remove the file when the script exits and manage the file if the script or machine crashes.

With Kicken's suggestion, set up your schedule for the script to be executed every 5 minutes.

Link to comment
Share on other sites

5 minutes ago, gw1500se said:

When the script starts check for a specific file in, say, \temp. If it is there, exit. If it is not then create the file and proceed. You will need to remove the file when the script exits and manage the file if the script or machine crashes.

 

Ok, but i have another question to you. Script is running and i write something in one folder but if someone click in button when the script is running? I'm inside the while loop, i will get the new rows added with executed=0?

5 minutes ago, gw1500se said:

With Kicken's suggestion, set up your schedule for the script to be executed every 5 minutes.

I don't like this option, because i have another jobs running and the server is very weak.

Link to comment
Share on other sites

29 minutes ago, gw1500se said:

Up to now, based on your OP, the implication was that script 2 was independent. Now you need to explain what that script does and how it interacts with 1 and 3.

Of course. Second point call an independent script (generate.php). The script include a while loop (point 3) and inside the "while" will read each line (with executed=0), with values stored in database i will call a form (via curl) and i go to save the html code returned (each iteration can take 40seconds).

Do you understood?

Link to comment
Share on other sites

1 hour ago, TrueMember said:

Why? I need lunch to execute the task immediately. I can shedule a job, but i need it run at every 5 minutos to check any entry to be executed. (i have another jobs and shouldn't not be a good solution)

Is there a reason you're running it as a separate task in the first place?  Most of the time this is done because the work can be time consuming and you don't want the user to have to wait and trying to accomplish that with on-demand task launching can be problematic in PHP in my experience.  The best way to accomplish that kind of separation is to simply keep the scripts separate entirely using either a scheduled task or service for one half.

There's generally nothing wrong with setting up a job to just run every minute (or whatever you require) to check for work.  If there is some, do it.  If there isn't, exit.   It might feel wasteful to run a script over and over with nothing to do but it's really not an issue and doesn't need to be avoided.  The downside to a scheduled task is you can only run it once a minute, if you need faster response times than a minute then you move to a service and either check for work more frequently or communicate with the service via a socket or a job server/queue server (gearman, redis, beanstalked, memcached, etc).

For example, I have an application that allows admins to import user accounts from LDAP.  The process can take a bit for large imports so similar to you I just INSERT a record into an ldap_import_request table from my web app.  On the server I use nssm to run a PHP script as a service and that script essentially runs a loop looking for new records.

while (true){
	$pendingRequests = loadPendingImportRequests();
	foreach ($pendingRequests as $request){
		processImportRequest($request);
	}

	sleep(1); //Avoid eating up CPU when idle.
}

You can get more advanced if you want, but I find this simple loop/table setup is fairly effective.

Link to comment
Share on other sites

1 hour ago, kicken said:

Is there a reason you're running it as a separate task in the first place?

Yes, actualy the results shows imediatly, but, i have many problem with many requests at same time, because, as i said before, the server is very weak and old (can't be changed). The server blocks and need be restarted some times a day.

So, I thought in that solution, each time every user click in button, the content go to the queue and can be executed individually. 

Answering to your question, while the task are running in background the user can continue doing her job and when the job is completed, will sent an email.

while (true){
	$pendingRequests = loadPendingImportRequests();
	foreach ($pendingRequests as $request){
		processImportRequest($request);
	}

	sleep(1); //Avoid eating up CPU when idle.
}

In you example, you have an infinite loop, it will never stop.

Thank you!

Link to comment
Share on other sites

41 minutes ago, TrueMember said:

In you example, you have an infinite loop, it will never stop.

Yes, that's the point.

It loops endlessly as a service checking for work to do.  When it finds some, it does it.  Otherwise it just sleeps, checking each second for new work. 

You can adjust the sleep period based on what your requirements are, or implement some method so it sleeps until specifically triggered to check for work (ie, through a socket).

 

Link to comment
Share on other sites

11 hours ago, kicken said:

Yes, that's the point.

It loops endlessly as a service checking for work to do.  When it finds some, it does it.  Otherwise it just sleeps, checking each second for new work. 

You can adjust the sleep period based on what your requirements are, or implement some method so it sleeps until specifically triggered to check for work (ie, through a socket).

 

Infinite loop is a good option? I don't think so, maybe i'm wrong.

Can i check inside loop if i have new rows in database? If yes, keep going the job, else, i will leave the cicly and change something to 0 (this means, the script not running).

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.