Показаны сообщения с ярлыком php. Показать все сообщения
Показаны сообщения с ярлыком php. Показать все сообщения

понедельник, 9 ноября 2009 г.

Mongo, Mysql, Ruby and PHP

Вот тут я сравнивал MongoDB и MySQL в Ruby и результат не сильно меня обрадовал, хотя на MongoDB возлагаю большие надежды.
Я провел некоторые дополнительные бенчмарки.
Скрипты для бенчмарков тут: http://github.com/latrommi/benchmarking
Результаты ниже.
----------------------------------------------------------------
For my English friends:
Some days ago I did some MongoDB benchmark tests.
Here is more extended version.
Benchmark scripts: http://github.com/latrommi/benchmarking
and results below.
----------------------------------------------------------------
Вывод один: это не значит, что MongoDB хуже MySQL, это значит, что для нее ещё не написано нормального, быстрого драйвера для Ruby.

Conclusion: no fast Ruby driver for MongoDB.

понедельник, 16 июня 2008 г.

PHP $argv ахтунг.

argv.php
#!/usr/local/bin/php -q
print_r($argv);

FreeBSD:
% ./argv.php a b c
Array
(
[0] => ./argv.php
[1] => a
[2] => b
[3] => c
)

Gentoo Linux:
$ ./argv.php a b c
Array
(
[0] => a
[1] => b
[2] => c
)


WTF?



UPD:
http://bugs.php.net/bug.php?id=44673

среда, 12 марта 2008 г.

PHP Daemon

А теперь немного извращений: демон на PHP.

ЧАСТЬ 1. ПИШЕМ ДЕМОНА.
Описание команд читать в мануалах. По-возможности, я даю на них ссылки.

declare(ticks=1);

$g_signals = array(
  'SIGTERM' => 0,
  'SIGHUP' => 0,
);

$g_ppid = null;
$g_pid = null;

dmn_sys_init(); // сердце демона!

$g_ppid = posix_getppid(); // pid родителя
$g_pid = posix_getpid(); // pid дочернего (текущего) процесса

// поехали!
while(1){
  // делаем что-то полезное.

  if($g_signals['SIGTERM'] == 1) // если получен сигнал завершения процесса, то не спеша, не паникуя тихонечко заканчиваем работу и выходим.
    break;

  if($sleep_time > 0)
    sleep(1); // спать одну секунду (на самом деле это идеологически не правильно, но для шаблона подойдет)
}

function dmn_sys_init(){
  global $g_pid;

  // 1. создаем дочерний процесс. при одном работающем это может быть не нужно, но если планируется запуск одного контрольного и нескольких рабочих процессов, то этот код необходим.
  if(-1 == ($g_pid = pcntl_fork()))
    exit("Could not fork.\n");

  // очень важный момент! Здесь определяем в каком мы процессе после разветвления.
  if($g_pid != 0){
    // 2. мы в родительском процессе
    // тут нам нужно отслеживать завершение дочерних процессов.
    // делается это банально просто: при создании процесса накручиваем счетчик дочерних процессов
    // при завершении дочернего процесса уменьшаем счетчик. Когда дочерних не осталось - выходим.
    // ждать завершения можно командой pcntl_wait.
    // написание этого кода я оставлю читателю в качестве домашного задания

    // для тех, кому лень думать есть приятные новости - дочерние процессы можно не ждать,
    // а делать в лучших традициях мира животных - выкидывать их из гнезда и тихонько помирать.
    exit("The end of parent process.\n");
  }

  // 3. мы в дочернем процессе!
  // отцепляем процесс от консоли
  if(-1 == posix_setsid())
    exit("Could not detach from terminal.\n");

  // устанавливаем хуки для обрабатываемых сигналов
  if(!pcntl_signal(SIGTERM, "dmn_sys_sig_handler"))
  exit("Could not setup SIGTERM handler.\n");

  if(!pcntl_signal(SIGHUP, "dmn_sys_sig_handler"))
  exit("Could not setup SIGHUP handler.\n");
}

// функция-хук обработки сигналов от операционной системы
function dmn_sys_sig_handler($signo)
{
  global $g_signals;

  switch ($signo){
  case SIGTERM:
    $g_signals['SIGTERM'] = 1;
    break;
  case SIGHUP:
    $g_signals['SIGHUP'] = 1;
    break;
  default:
    $g_signals['OTHER'] = $signo;
  }
}


ЧАСТЬ 2. ПИШЕМ RC СКРИПТЫ.
Здесь пример примитивнейшего RC скрипта для Gentoo.
RC скрипт и PHP файлы записать в /etc/init.d/my-php-daemon и /usr/lib/my-php-daemon соответственно.

#!/sbin/runscript

depend() {
  # выставляем зависимости
  need net
}

start() {
  # показываем юзеру что мы делаем
  ebegin "Starting my PHP daemon"

  # ведем лог
  echo --------------------- >> /var/log/my-php-daemon/rc.log
  date >> /var/log/my-php-daemon/rc.log

  # запускаем демоненка
  php-cgi -f /usr/lib/my-php-daemon/index.php >> /var/log/my-php-daemon/rc.log

  # конец
  eend $?
}

stop() {
  # показываем юзеру что мы делаем
  ebegin "Stopping my php daemon"
  # останавливаем демона так - ищем процесс, выполняющий файл /usr/lib/my-php-daemon/index.php и посылаем ему сигнал SIGTERM.
  # внимание! если таких процессов несколько, то все они получат сигналы SIGTERM.
  pkill -TERM -f /usr/lib/my-php-daemon/index.php

  # ведем лог
  date >> /var/log/my-php-daemon/rc.log
  echo --------------------- >> /var/log/my-php-daemon/rc.log

  # конец
  eend $?
}


Таким образом все варнинги и ошибки PHP будут сыпаться в /var/log/my-php-daemon/rc.log, но, к сожалению, без даты. Добавить дату - это будет читателю второе домашнее задание.

Конечно, мануал не претендует на полноту и безупречность, но это лучше, чем ничего. А еще лучше для простого изучения.

БОНУС-ТРЕК
Поскольку PHP бывает весьма не предсказуем, то для контроля работы демона можно написать небольшой cron скриптик:

$g_vs_gw = "http://gw1.viasms.ru?"
$g_vs_eid = "12345";
$g_vs_password = "secure_word";

$g_needed = array(
  'my-php-daemon' => array(
    'regexp'=>'/php-cgi.+my-php-daemon/',
    'reset_cmd'=>'/etc/init.d/my-php-daemon zap --nocolor',
    'start_cmd'=>'/etc/init.d/my-php-daemon start --nocolor'
  ),
);

// fill array with system fields
$needed = array();

foreach($g_needed as $key=>$val){
  $needed[$key] = $val;
  $needed[$key]['running'] = 0;
}

$exec = shell_exec("ps -C php-cgi -o pid= -o command=");
$pss = explode("\n", $exec);

foreach($needed as $key=>$val)
  if(!$val['running'])
    foreach($pss as $ps)
      if(preg_match($val['regexp'], $ps))
        $needed[$key]['running'] = 1;

foreach($needed as $key=>$val){
  if(!$val['running']){
    print date("Ymd-His") . "\n";

    print shell_exec($val['reset_cmd']);
    $cmdresult = shell_exec($val['start_cmd']);
    print $cmdresult;

    $msg = $key . ' service is down. ' . $cmdresult;
    $pass = md5(md5($g_vs_password) . $msg);

    $url = $g_vs_gw . '?' .
      'eid=' . urlencode($g_vs_eid) .
      '&pass=' . urlencode($pass) .
      '&msg=' . urlencode($msg);

    print $url . "\n";
    readfile($url);
    print "\n";
  }
}


Этот скрипт во время своего запуска проверяет все демоны, указанные в массиве $g_needed. Если один из них не работает, то скрипт сбрасывает его состояние (zap) и запускает снова. Ориентировано, опять таки, на дистрибутив Gentoo. Для подстройки для вашего дистрибутива подкрутите элементы массива reset_cmd и start_cmd.

О результате выполнения пишет лог и отправляет SMS сообщение с текстом о состоянии запуска.
В качестве SMS шлюза используется сайт viasms.ru. Для этого в переменных $g_vs_eid и $g_vs_password надо указать id и пароль события.

В результате, работы скрипта к вам придет SMS сообщение примерно следующего содержания:


my-php-daemon service is down. Starting my PHP daemon [ ok ].


И вы сможете дальше спокойно пить пиво :О)

понедельник, 10 декабря 2007 г.

PDT VS PHPEclipse

Сравнение. Скорее просто перечисление недостатков.

http://www.eclipse.org/pdt/. Eclipse update: http://download.eclipse.org/tools/pdt/updates/
- нет проверки синтаксиса на использование необъявленных переменных;
- в Outline показывает все функции проекта, очень много, не удобно;
- в Content Assist неправильно отсчитывает запятые в параметрах функции;
- жутко глючный фолдинг.

http://phpeclipse.sourceforge.net/. Eclipse update: http://phpeclipse.sourceforge.net/update/nightly/
- Content Assist при обнаружении множества функций с одним названием в проекте не показывает вообще ничего;
- нет возможности подсветить числа;
- редко обновляется.
Среди плюсов:
+ проверка синтаксиса на наличие необъявленных/неинициализированных переменных.

В многом остальном проекты похожи.

После длительного использования PDT нашел для себя phpeclipse, который порадовал своим пусть пока одним, но очень большИм преимуществом (см. выше). Посмотрим как себя поведет дальше.