klopp: (размахиваю кувалдой)
На самом деле не хак, а вовсе документированная возможность.

Имеем: около 500 тысяч (полмиллиона) селектов в час. Внутри каждого из них prepared statements кэшируются внутри DBI. В результате чего часов через 10 работы скрипт разбухает так, что всем вокруг плохеет. Отменить кэширование нельзя, изменить архитектуру тоже (на самом деле нужно, но это не в обозримом будущем, а работать должно сейчас).

Напрашивается простое решение: периодически закрывать соединение с базой (что автоматом очищает память) и соединяться снова. Но возникает вопрос: когда переподключаться? По времени не вариант, нагрузка плавающая, зависит от кучи внешних факторов и не прогнозируется. Значит, надо считать селекты. Но как? Выискивать по 50k cloc все места - убиться проще.

Вот тут и пригождается атрибут DBI::Callbacks. Сразу после соединения с базой вешаем на ключевые функции DBI коллбэки, в которых дёргаем счётчик (его ID передаётся явно, так как в общем случае можем подключаться не к одной базе):

sub set_dbh_callbacks
{
    my ( $self, $dbh, $counter_name ) = @_;
    
    $dbh->{Callbacks} = 
    {
        do                 => sub { ++$self->{$counter_name}; return; },
        prepare            => sub { ++$self->{$counter_name}; return; },
        selectrow_array    => sub { ++$self->{$counter_name}; return; },
        selectrow_arrayref => sub { ++$self->{$counter_name}; return; },
        selectrow_hashref  => sub { ++$self->{$counter_name}; return; },
        selectall_arrayref => sub { ++$self->{$counter_name}; return; },
        selectall_hashref  => sub { ++$self->{$counter_name}; return; },
        selectall_array    => sub { ++$self->{$counter_name}; return; },
        selectcol_arrayref => sub { ++$self->{$counter_name}; return; },
    };
    $self->{$counter_name} = 0;
}


Voilà! В любой (удобный нам) момент мы можем проверить значение счётчика и что-то предпринять. Значение, при котором это нужно делать, подбирается экспериментально :)
klopp: (размахиваю кувалдой)
Они такие прикольные.

Не понимают, что между C и С++ огромная разница.
klopp: (Saigon)
Когда перевёлся в ЛГУ из военмеда (это была отдельная эпопея), попробовал ходить на "язык". Через пару занятий плюнул, пришёл на кафедру и нахально так заявил: а можно сразу сдать госы? Офигели, но спросили где такой наглый учился. Ответ "171" пробил все бюрократические барьеры (известное место, как и "239"). Сдал, получил печать. Ха, мы такое в пятом классе щёлкали.

Потом, раз свободные пары появились, решил походить на английский. И вот тут случился большой проёб. Оказалось что я, ни разу не учивший английский язык, знаю его лучше тех, кто учил его в школе! Ну и забил.

С тех пор читать/писать умею.
Разговаривать на "родном" французском - да запросто. А вот Инглиш вводит в ступор. Слышу, понимать могу. Но сказать ничего не получается.

Надо было тогда тратить время не на херню всякую и понтоваться, а учиться.
klopp: (Котя)
А отходняк от операции надо пережить без эксцессов:

klopp: (размахиваю кувалдой)
Таки не удержался, форкнул. Пара мелочей, но до автора, как это часто бывает, не достучаться.

А штука на самом деле мегакрутая, умеет postgresql, mysql и oracle.
klopp: (Default)
... и обратно часа два, немного вариантов. Основной у меня - поспать :) Но можно и позадротстововать. Цель - развивая только силу:



Пройти дракошу на 124 уровне:



Что будет в избушке под номером 125, последней, даже не догадываюсь, но игра на этом закончится, поэтому и...



При этом пройти "чисто", без покупки доп. средств (там их много, на каждый случай свои):



Наверняка с ними проще, тем более что "финансы" позволяют закупить их столько, что и самому мечом махать не придётся. Но это дело принципа :)

В общем, прикольно: Good Knight Story. Отзывы, как обычно, разнообразные :)
klopp: (Котя)
Фейсбучичек принёс статеечку. Глаз зацепился за это:

мейн-кунов - самых больших одомашенных кошек в мире


Их что, вообще без мозгов выпускают с журфака? Или это сознательная желтизна? А ведь формально и не придерёшься, но как звучит...
klopp: (размахиваю кувалдой)
Есть такой шикарный модуль: Data::Printer (он же DDP). Один из инструментов уровня must have, Data::Dumper по сравнению с ним как плотник супротив столяра :) И, тем не менее, как легко его можно уложить:
#!/usr/bin/perl

use Modern::Perl;
use DDP;
use Scalar::Array;

my $data = [ 1, 2, 3 ];
p $data;

round_robin( $data );
p $data;

Вывод:

$ ./testrr.pl
\ [
    [0] 1,
    [1] 2,
    [2] 3
]
Segmentation fault

Почему - очевидно же :-) Во всяком случае на интуитивно-понятно алгоритмическом уровне, на уровне реализации надо разбираться подробней.
klopp: (Saigon)
На портале государственных услуг Российской Федерации (gosuslugi.ru) специалисты компании «Доктор Веб» обнаружили внедрённый неизвестными потенциально вредоносный код. В связи с отсутствием реакции со стороны администрации сайта gosuslugi.ru мы вынуждены прибегнуть к публичному информированию об угрозе.

Подробности тут.
klopp: (Default)
Цитата, в скобках мои комментарии:

Мы находимся в поиске Senior Web Developer’a.
Основные требования:

· Умение читать, понимать и улучшать чужой код (хе-хе...);
· Python 2.7 - Уровень Middle+;
· JavaScript (ES5) - Уровень Middle+;
· Angular 1.4+(<2);
· Навыки верстки: HTML/HTML5/CSS/CSS3 (реально этим заниматься не придётся, но представление иметь - обязательно);
· Знание основ реляционных СУБД и SQL (постгрес, не шарахаться от выноса логики в базу; понимание что такое JSONB и с чем его едят - нужно);
· Навыки работы с git.

Подробней: https://spb.hh.ru/vacancy/21481669
klopp: (размахиваю кувалдой)
Наблюдение: продать нетбук с линуксом - нереально. Даже если там всё летает и работает как швейцарские часы. Сначала нужно извратиться, поставить на него семёрку, огрести кучу геморроя с драйверами, в конечном итоге получить какого-то неповоротливого уродливого монстра, вот тогда им и заинтересуются...
klopp: (Saigon)
На столбе у станции Старый Петергоф :)

klopp: (размахиваю кувалдой)
Что выведет вот этот код?
#!/usr/bin/env perl

use Modern::Perl; 
my ( $var, @data ) = ( qw/Perl Ruby PHP C/ );
for $var ( @data ) {
  $var = 'C++' if $var eq 'C';
}
say join( ',', @data, $var );

Правильный ответ:

Read more... )
klopp: (размахиваю кувалдой)
Долго меня бесила невозможность отключить болд в терминале PAC Manager. Надоело :)
klopp: (Default)
Работая на полуудалёнке, некоторые вещи, происходящие в твоей же конторе, узнаёшь только из контактика :)
https://vk.com/wall-201069_985
klopp: (Saigon)
Загадочное нечто. Что оно делало между Швецией и Россией с 12 февраля по 1 марта? Почему после Внуково начали говорить на непонятном языке? Как оно умудрилось так похудеть за сутки? Кликабельно:

klopp: (Saigon)
...эти модные приколы.
Только чистый C,
по заветам старой школы!


klopp: (размахиваю кувалдой)
Конечно, их уже навалом есть. Но что бы свой не написать, раз процентов 80 кода по другим рабочим скриптам болтается? Ну и на баше :)

Основная идея в том, что списки файлов для потоков формируются по-умному. Ну, как по-умному, относительно :) См. Partition problem # The greedy algorithm. Все файлы, которые меньше указанного размера, идут отдельным потоком. А те, что больше - делятся на части как можно более близкого размера.

Полный список ключей:
Usage: prsync.sh [options]
Valid options, * - required:
    -src   DIR   *  source directory
    -dst   DIR   *  destination directory (see '-x' option)
    -s     SIZE     file size to put it in papallel process, default: '10M' 
                    about size's format see 'man find', command line key '-size' 
    -p     N        additional processes, >0, default: '2'
    -v              be verbose
    -c              cleanup '-dst' directory before sync
    -x              print processes info and exit (no '-dst' required)
    -d              show debug info (some as '-x', but launch sync) 
    -k              keep temporary files 
    -b     N        show N biggest files with -x, default: '4'  
    --     OPT      rsync options, default: '-a --delete -q'


Для экспериментов есть ключи -v, -b, -k, -x. При указании -x запуска rsync не происходит, поэтому его удобно использовать для подбора параметров. Например:

$ sudo ./prsync.sh -src /home/postgres/pg95/data/base/16385 -s 1G -x
Additional processes:
 files:        0, bytes:                  0 (/tmp/prs-v6lKZe.include)
 files:        0, bytes:                  0 (/tmp/prs-GVbwQe.include)
Main process:
 files:     1387, bytes:     30 219 743 748 (/tmp/prs-qzGVYd.include)
Biggest files:
Rsync arguments: -a --delete -q


Обломс, падаем до 100M:

$ sudo ./prsync.sh -src /home/postgres/pg95/data/base/16385 -s 100M -x 
Additional processes:
 files:       35, bytes:     13 422 071 808 (/tmp/prs-KO7Zlt.include)
 files:       36, bytes:     13 527 990 272 (/tmp/prs-Z9e4at.include)
Main process:
 files:     1316, bytes:      3 269 681 668 (/tmp/prs-3P4rut.include)
Biggest files:
      1 073 741 824 bytes '/175490'
      1 073 741 824 bytes '/175489'
      1 073 741 824 bytes '/175487.2'
      1 073 741 824 bytes '/175487.1'
Rsync arguments: -a --delete -q


Уже лучше, но...

$ sudo ./prsync.sh -src /home/postgres/pg95/data/base/16385 -s 500M -x 
Additional processes:
 files:       10, bytes:      8 813 338 624 (/tmp/prs-Uy9twY.include)
 files:        9, bytes:      8 315 084 800 (/tmp/prs-79klmY.include)
Main process:
 files:     1368, bytes:     13 091 320 324 (/tmp/prs-jMVkFY.include)
Biggest files:
      1 073 741 824 bytes '/175490'
      1 073 741 824 bytes '/175489'
      1 073 741 824 bytes '/175487.2'
      1 073 741 824 bytes '/175487.1'
Rsync arguments: -a --delete -q


Во! Чего-то более приличного для 2 дополнительных процессов добиться с этим набором файлов уже не выйдет. А больше 2 (фактически трёх) - это уже индивидуально.

Да, живёт тут: Github # prsync.
klopp: (размахиваю кувалдой)
По поводу вот этого патча отписался автор AStyle:
Added to astyle as "attach-closing-while".
It will be in the next commit.

Expand Cut Tags

No cut tags

September 2017

S M T W T F S
     1 2
3456789
10111213141516
17181920212223
24252627282930

Syndicate

RSS Atom