 
			
				15.02.2012, 06:48
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 Новичок 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 05.09.2010 
					
					
					
						Сообщений: 2,298
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	| 
	
	
		
		
			
			 
				PHP: несколько AJAX запросов с долговременной обработкой на сервере
			 
			
		
		
		
		Мне нужно получить данные с серверного скрипта, который обрабатывает и возвращает ответ, к примеру, через минуту. Если я посылаю, например, сразу два AJAX запроса, то ответ обоих я получу через две минуты (первый — через минуту, второй — через две). Как сделать так, чтоб один клиент мог своими действиями создавать два независимых процесса (а не один процесс со стеком запросов) на сервере, чтоб данные начали обрабатываться сразу, а ответ пришел через минуту, а не через две? 
		
	
		
		
		
		
		
			
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				15.02.2012, 07:13
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 что-то знаю 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 24.05.2009 
					
					
					
						Сообщений: 5,176
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	| 
	
	
		
		
		
		
		 почитай про pcntl_fork() в PHP 
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				17.02.2012, 03:27
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 Новичок 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 05.09.2010 
					
					
					
						Сообщений: 2,298
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	| 
	
	
		
		
		
		
		 Если я правильно понял pcntl_fork распараллеливает работу на сервере. Т. е. клиент послал один запрос, сервер создал несколько потоков... А я посылаю много запросов, эти запросы всё равно будут храниться в стеке. 
		
	
		
		
		
		
		
			
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				17.02.2012, 12:19
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 что-то знаю 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 24.05.2009 
					
					
					
						Сообщений: 5,176
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		
	
 
	| 
		
			Сообщение от FINoM
			
		
	 | 
 
	| 
		Т. е. клиент послал один запрос, сервер создал несколько потоков...
	 | 
 
	
 
 Не совсем правильно, я так понял вы хотите разгрузить клиента от ожидаемых запросов. Для этого и есть fork. Тоесть все просто. 
Делаете запрос на сервер, сервер создает дополнительный поток. А из основного выходит, тоесть отпускает клиента. Клиент же в свою очеред через пару минут снова обращается к серверу для получения информации о завершении обработки данных в потоке, если порожденный поток выполнил свою работу, он к примеру на сервере устанавливает некий триггер в сессии/БД это уж вам решать как сохранить, клиент обращается к серверу и проверив триггер понимает завершен поток или нет, если да то получает уже данные обработанные из сессии/БД.  
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				17.02.2012, 13:02
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 что-то знаю 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 24.05.2009 
					
					
					
						Сообщений: 5,176
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		примерно так: 
<?php
	// Создаем сессию
	$expireTime = 60*60*24*30;
	session_set_cookie_params( $expireTime );
	session_start();
	// Подготавливаем массив процессов
	if ( !isset( $_SESSION['forks'] ) ) {
		$_SESSION['forks'] = array();
	}
	if ( isset( $_GET['action'] ) ) {
		switch( $_GET['action'] ) {
			case "startProcess":
				// генерим уникальный ключ для процесса
				$processId = md5( mktime() );
				// ставим процессу статус не завершен
				$_SESSION['forks'][ $processId ] = false;
				// создаем процесс
				$pid = pcntl_fork();
				// С этого участка кода сразу же начнет работать дочерний поток
				if ( $pid == -1 ) {
					// Если поток создать не удалось
					// Уничтожаем инфу о процессе
					unset( $_SESSION['forks'][ $processId ] );
					exit( "Create process failed" );
				} else if ( $pid ) {
					// Сюда попадет родительский поток, тоесть основной
					exit( "Process started. Current process PID: ".$processId );
				} else {
					// сюда попадет дочерний/порожденный поток
					// ......... обрабатываем данные
					// ставим статус завершен
					$_SESSION['forks'][ $processId ] = true;
					// завершаем процесс
					exit();
				}
				break;
			case "processStatus":
				// Если передали ID процесса и он есть в массиве процессов
				if ( isset( $_GET['pid'] ) && isset( $_SESSION['forks'][ $_GET['pid'] ] ) ) {
					// Проверяем статус
					if ( $_SESSION['forks'][ $_GET['pid'] ] ) {
						// Уничтожаем инфу о процессе
						unset( $_SESSION['forks'][ $processId ] );
						$status = "complete";
					} else {
						$status = "working";
					}
					exit( "Process status ".$status );
				}
				exit( "Process not found" );
				break;
			default;
		}
	}
?>
 
		
	
		
		
		
		
		
		
	
		
			
			
	
			
			
			
			
			
				 
			
			
			
			
			
			
				
			
			
			
		 
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				17.02.2012, 13:07
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 что-то знаю 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 24.05.2009 
					
					
					
						Сообщений: 5,176
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	| 
	
	
		
		
		
		
		 запускать это дело примерно так: 
Стартануть процесс: 
http://somesite.com/fork.php?action=startProcess 
 
Проверить статус: 
http://somesite.com/fork.php?action=processStatus&pid={PROCESSID} 
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				20.02.2012, 13:48
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 
 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 27.12.2008 
					
					
					
						Сообщений: 4,201
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		
	
 
	| 
		
			Сообщение от FINoM
			
		
	 | 
 
	| 
		Как сделать так, чтоб один клиент мог своими действиями создавать два независимых процесса (а не один процесс со стеком запросов) на сервере,
	 | 
 
	
 
 [telepath mode]вызывать session_write_close как можно быстрее или не запускать 2 одинаковых запроса в ff/chrome[/telepath mode]  
		
	
		
		
		
		
		
		
		
						  
				
				Последний раз редактировалось x-yuri, 20.02.2012 в 14:47.
				
				
			
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				20.02.2012, 14:48
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 
 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 27.12.2008 
					
					
					
						Сообщений: 4,201
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		кстати, интересно, что опера выполняет один запрос, если в двух вкладках попытаться открыть один и тот же url    
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				18.03.2012, 01:19
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 Новичок 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 05.09.2010 
					
					
					
						Сообщений: 2,298
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		Ребята тупо удалили сессию, запросы стали обрабатываться параллельно    
		
	
		
		
		
		
		
			
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				20.03.2012, 19:50
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 
 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 27.12.2008 
					
					
					
						Сообщений: 4,201
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	| 
	
	
		
		
		
		
		 потому что на открытый файл сессии ставится блокировка, нельзя из двух процессов получить доступ к сессии. Т.е. либо не использовать в этом месте сессию, либо закрывать побыстрее. 
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
 
 
 
 
 
	 | 
 
 
 |