1

Here is my problem : I have an application that allows users to synchronize their data with social networks. The problem is that each synchronization can take up to 10 seconds. So I would like to trigger the synchronization in "background" task, and if possible parallelize all synchronisation.

Currently, my script looks like :

$user =  user::login($username, $password);
/* Do some treatments, display the home page */ 
$user->synchronize();
/* END OF LOGIN SCRIPT */

and in my user.class.php, I have something like

public function synchronize(){
 $Networks = socialNetworks::getByUserId($this->userid);
 foreach($Networks as $n) $n->synchronize();
}

and finally in the socialNetworks.class.php, I have implemented all the synchronization scripts for each social network (fb, linkedin, google+, ...).

Note that I don't need to wait for the result of the synchronization when logging in.

So I have 2 problems here :

  1. when calling $user->synchronize(); the login script is blocked until the end of the loop
  2. the loop itself is very long, and I would like to launch parallel "threads", to make it faster when calling the synchronize() method (I have some Ajax triggering this action).

What would you suggest to optimize this ?

Thanks.

Jean-Marc Dormoy
  • 129
  • 1
  • 2
  • 9
  • 2
    http://stackoverflow.com/questions/209774/does-php-have-threading – looper Nov 20 '12 at 13:18
  • Things never really get faster when you run them in parallel. Actually, they get slower. – arkascha Nov 20 '12 at 13:20
  • @arkascha In this case, most of the time is spent waiting for the remote servers, so the operation will complete faster if the waiting is done in parallel. – Klas Lindbäck Nov 20 '12 at 13:55
  • yes the bottleneck is not with the synchronisation scripts but indeed with the remote server. The treatment then is just to check some data from the remote application versus the data in the local DB. – Jean-Marc Dormoy Nov 20 '12 at 14:15

3 Answers3

0

There are 2 ways.

  1. Use exec() to make multiple syscalls like exec("php /path/to/script?networkId=1 > /dev/null 2>/dev/null &")
  2. use pcntl_fork() function which works only in Linux.
BenMorel
  • 34,448
  • 50
  • 182
  • 322
nkamm
  • 627
  • 5
  • 14
0

One option is to use Gearman, and offload this work to it's workers.

You basically create a PHP script that does some work. Then you tell it to do that work from your login script, and the work will be done in the background outside of the request.

Jan Hančič
  • 53,269
  • 16
  • 95
  • 99
  • that looks very interesting. If I well understand the first articles I read, I can offload each task to the Gearman server that send it to its workers, and I can wait for the result (if I need to do some further treatments) or not (it this is just the initial synchronization). – Jean-Marc Dormoy Nov 20 '12 at 14:31
  • btw, is it a good idea to have dedicated virtual machines for one or several Gearman server ? – Jean-Marc Dormoy Nov 20 '12 at 14:33
  • first comment: yes second comment: usually you'll have one gearman server, and possibly multiple workers. You can run all this on the same machine or multiple machines. Start with oe machine and then add new machines running workers if necessary. – Jan Hančič Nov 20 '12 at 15:08
  • If an answer solves your question you should up-vote it & accept it. – Jan Hančič Nov 21 '12 at 08:52
0

Her is an blog post about asynchronous processing with php:

http://robert.accettura.com/blog/2006/09/14/asynchronous-processing-with-php/

    <?php
      include 'AsynchronousProcessing.php'

      launchBackgroundProcess('php /path/to/task1.php');
      launchBackgroundProcess('php /path/to/task2.php');
      $class->SomeWork();
      $class->SomeOtherWork();
?>
eriksv88
  • 3,482
  • 3
  • 31
  • 50