3

Objects:

  • Object Sale
  • n Object User will participate on Object Sale
  • Each User can create one Object Agent
  • Each Agent will generate n Object Licitation (from time to time and with some conditions) for the object Sale

Goal:

Create a function that when a Sale has only 5 seconds left to end, will check all the Agents that there are for this Sale and post a licitation from the Agent that hasn't made a licitation on this sale the longest

This is something that needs to be continuously running since this agents would be in charge to replace users on posting licitations allowing them to be away during auctions.

My question

Updated (My question wasn't clear enough):

At index page of the sales I have a script with javascript that calculates the time left on a sale, so I can know when a sale should call the function to check for agents and place their bids, but my newbie question is: if I make a call for the function at this page, will this only work if the user has the page open? Or if he closes the function won't be called anymore? Because I need this to still work even the user closes webpage. DaMacc already answered that this doesn't work

Updated (05/01/2010)

I've already created this function. The function will find all the sales that have 5 seconds left to end, then it will search all the agents and then place a bid from the agent that hasn't made a licitation on the selected sale the longest. Now i need this function to be called every second. I was going to use cron but cron has 1-minute boundaries. And I need this function to run on the server and not depend on the user that owns the agent.

Any suggestions?

PS: there are some auctions websites that have this kind of bidagents i'm trying to do, I could reffer one to use as example... But i'm not sure i'm allowed to do that here... :S

Thanks.

Canastro
  • 2,979
  • 30
  • 39
  • It will indeed only work when the user has the page open, so the answer of scythah is your solution. – DaMacc Jan 02 '10 at 23:25

4 Answers4

5

Create your normal function to do whatever it is you need to do and then use something like cron to set it up as a task to run every X amount of time.

Edit to expand on comments

In that case you are probably better off combining a few solutions. As mentioned in this question, I would recommend that you use cron to call a script every minute and in that script you run your process in a loop.

Some things to consider:

  • How long will each execution take?
  • Will you need to time_sleep_until at the end of each loop or will your script take longer than 1 second to run, in which case you will need to be calling the script multiple times from cron.
  • Be sure to keep track of how long your script has been running for as you don't want to have the situation where every minute you are taking up more and more resources as the script called the previous minute hasn't finished yet.

At the start of the script, take note of the current time, then at the start of each loop, check whether a minute has passed since the start of the script, if it has, exit the script (as another script will have taken over now thanks to cron).

Hope this helps. Let me know if this doesn't make a lot of sense and I'll try to clear it up a bit.

Community
  • 1
  • 1
Blair McMillan
  • 5,299
  • 2
  • 25
  • 45
  • But my big problem is that I don't know the frequency that my function needs to be called. Each Agent object would call this function only if: the last user to place a Licitation on a Sale wasn't the one that created this agent and if the difference between current time and limit date at object Sale is equal to 5 seconds. – Canastro Jan 02 '10 at 22:47
  • As php does not have multithreading or a constant background process, that is the correct way to do that. Just put your objects sales in the database and run a special, that queries the database for all items, that are due in less than X days and process the information. You can run the script every minute and if there are no objects, that need to be processed, it does nothing. – FlorianH Jan 02 '10 at 22:47
  • This is something that needs to be continuously running since the goal of this website would be an auction website, and this agents would be in charge to replace users on placing bids allowing them to be away during auctions. There would be many items on sale, and which one with diferent time end, so run a script each minute wouldn't work :S – Canastro Jan 02 '10 at 22:53
  • Then run it every every second? – DaMacc Jan 02 '10 at 23:20
  • If I have like 200 sales. 3 Agents for each Sale. In this function I have to, for each sale with time end = 5 seconds, select all agents, check for all licitations posted for this sale and then create a licitation (select on sales table, licitations table, agents table, users table, insert on table licitations, update on table sales and agents). Wouldn't this be too heavy to call every second? I don't know much about php performance... But yes, it seems to be a possible way to do it, and I'll try it! – Canastro Jan 02 '10 at 23:47
  • 2
    The following question will probably be of interest you to: http://stackoverflow.com/questions/1778540/execute-php-script-every-40-miliseconds – Blair McMillan Jan 03 '10 at 15:25
  • Well the cron solution doesn't work, since it can only be called to run every minute, and I need this function to be invoqued every second. – Canastro Jan 05 '10 at 02:17
  • Thanks for the new input, seems to be a good option... I'll try to solve it that way ;) – Canastro Jan 05 '10 at 17:15
  • I've found out a solution using Shell class from cakephp, Cron and using some tips that you gave me. so thank you :D – Canastro Jan 08 '10 at 01:48
3

I wonder if this is what you are looking for:

function execInBackground($cmd) {
    if (substr(php_uname(), 0, 7) == "Windows") {
        pclose(popen("start /B ". $cmd, "r"));
    } else {
        exec($cmd . " > /dev/null &");
    }
}

You can then start a php process in the background using the following method:

execInBackground("php path/to/file.php " . $param01 . " " . $param02);
// where $param01 and $param02 are optional values that you may want to
// send to the page. Equivalent to GET parameters of URL.
// You can include as many parameter values as you want.

//Example:
execInBackground("php automation/bidChecker.php daniel 53.25");
// automation/bidChecker.php is the file to be executed
// daniel can be the username
// 53.25 can be the bid value

And in the PHP file that runs in the background, you can access the parameter values using the following method:

$param01 = $argv[1]; // assigns daniel as value
$param02 = $argv[2]; // assigns 53.25 as value

This process can be started from within a script run when the user does something. It will also keep on running even if the user leaves the page and until you programatically break the operation.

I really don't know if this is what you are looking for. If so, you got it now.

Nirmal
  • 9,391
  • 11
  • 57
  • 81
  • Does it work the same way to Linux? Or just need to make a litle adjustments? Thks for the answer, it seems to be a good way to solve my problem... – Canastro Jan 05 '10 at 03:27
  • It should work in Linux without any modification. But give it a try for yourself. I'm on Windows stack and haven't got a chance to work with Linux. – Nirmal Jan 05 '10 at 04:10
  • 1
    Your `execInBackground` function won't work on WINNT as it doesn't have Windows in it's uname. – Blair McMillan Jan 05 '10 at 10:28
  • +1 @Blair - Thanks for that info. Would appreciate if you can post a hack for that. This code is direct from my environment where we run Windows Server 2008 R2. – Nirmal Jan 05 '10 at 10:39
  • See my post in http://stackoverflow.com/questions/1987402/php-check-what-server-the-application-is-running-on/1987412#1987412, otherwise you could try matching `win` and either strtoupper or strtolower the inputs. Not sure if there's any OS's that have 'win' in them other than Windows – Blair McMillan Jan 05 '10 at 19:34
1

Use a Queue, like Zend_Queue: http://framework.zend.com/manual/en/zend.queue.html . Just run an infinite loop (or two) and dispatch messages sent from your web application

Valentin Golev
  • 9,965
  • 10
  • 60
  • 84
0

Have you looked into using Javascript at all for this? If you have certain events that trigger the need to run this check, it may be the way to go.

You could write a js function included on every page that uses the the setInterval/clearInterval javascript functions to send an AJAX request to your server every few seconds and could send a different response back to the browser based on whether the conditions were met or not. (bandwidth may be an issue with this though)

I would recommend looking into jQuery and using it's AJAX functions for this.

munch
  • 6,311
  • 4
  • 23
  • 27
  • 4
    Relying on clients for essentials like this is a mistake. – gnud Jan 03 '10 at 00:35
  • @gnud, you're right. I answered this before he updated the question. It wasn't as clear to me then what he was trying to do. It is, indeed, the wrong solution – munch Jan 03 '10 at 07:36