Как стать автором
Обновить
4
0

Пользователь

Отправить сообщение

Где как на самом деле.


Замечу, что мы — команда разработки десктопных приложений для Windows, поэтому сборка и выкладка docker-образов пока что не про нас (вот ASP.NET Core команда — это другое дело, может скоро и их затащим).


В общем:


  1. Кое-где закидываем через SSH (job-а запускается под linux и scp-шкой закидывает нужные файлы).
  2. Кое-где кидаем через WebDAV (job-а запускается также под Linux и у нас кто-то, примонтировав через davfs2 закидывает rsync-ом, а кто-то типа меня через кастомный скрипт на powershell core).

А непосредственно доставкой до клиента после выкладки на публичный сервер занимается самописный обновлятор (сделанный примерно во времена .NET 4). Так исторически сложилось + пока функционала более, чем хватает.


Обновлятор при запуске ПО и/или раз в некоторый интервал времени лезет на сервер, смотрит нет ли новой версии и, если есть, скачивает её инсталлер и даёт пользователю выбор: запустить сразу или запустить после закрытия программы (эта же идея, к примеру, в Paint.NET реализована).

Если говорить о совсем нормальном варианте, то вот. Это, скажем так, мое видение DDD. Вдохновлялся у Мэтью:

weierophinney.net/matthew/archives/202-Model-Infrastructure.html
weierophinney.net/matthew/archives/201-Applying-ACLs-to-Models.html
weierophinney.net/matthew/archives/200-Using-Zend_Form-in-Your-Models.html

Если же говорить о конкретно вашем случае, с использованием только Table Gateway, то я бы делал так:

Пусть нам изначально ставят задачу вывести список юзеров. Нет ничего проще.

class Users extends Zend_Db_Table_Abstract
{
    protected $_primary = 'id';
    
    public function getAll()
    {
        return $this->fetchAll();
    }
}

Казалось бы, ну что за идиотизм делать такую функцию, кому она нужна, если можно напрямую вызвать fetchAll???
Но тут начальство ставит нам задачу: выводить список юзеров + количество комментариев каждого юзера.
Все, что нам нужно, слегка модифицировать наш метод:
class User extends Zend_Db_Table_Row_Abstract
{
    protected $_commentsCount = 0;

    public function init()
    {
        parent::init();
        if (array_key_exists('commentsCount', $this->_data)) {
            $this->_commentsCount = (int)$this->_data['commentsCount'];
            unset($this->_data['commentsCount']);
        }
    }

    public function getCommentsCount()
    {
        return $this->_commentsCount;
    }
}

class Users extends Zend_Db_Table_Abstract
{
    protected $_primary = 'id';
    
    protected $_rowClass = 'User';

    public function getAll()
    {
        $select = $this->select()
            ->from(array('u' => 'Users'))
            ->joinLeft(array('c' => 'Comments'), 'c.user_id = u.id', array(
                                                   'commentsCount' => new Zend_Db_Expr('COUNT(c.*)')
                                               ))
            ->group('u.id');
        return $this->fetchAll($select);
    }
}

При таком решении никаких изменений в контроллере не потребуется.
Не нравятся join'ы??? Можно и без них, если правильно настроено кэширование:
class User extends Zend_Db_Table_Row_Abstract
{
    protected $_commentsCount;

    public function getCommentsCount()
    {
        if ($this->_commentsCount === null) {
            /**
             * @var Zend_Db_Table_Abstract $comments
             */
            $comments = $this->getTable()->getReference('Comments');
            $select = $comments->select()
                ->columns(array('commentsCount' => new Zend_Db_Expr('COUNT(*)')))
                ->where('user_id = ?', $this->id);
            $row = $comments->fetchRow($select);
            $this->_commentsCount = (int)$row->commentsCount;
        }
        return $this->_commentsCount;
    }
}

class Users extends Zend_Db_Table_Abstract
{
    protected $_primary = 'id';

    protected $_rowClass = 'User';

    public function getAll()
    {
        return $this->fetchAll();
    }
}
для блокировки достаточно атомарной операции добавления ключа (которая фейлится, если такой ключ уже существует):
while (true) {
   if ($mc->add('lock', getmypid())) {
        try {
              // ... work work work
        } catch (Exception $e) { // no 'finally' in PHP =(
              $mc->delete('lock');
              throw $e;
        }
        $mc->delete('lock');
        break;
   }
   usleep(rand(10, 1000));
}


Ненамного, но все же проще.
НЛО прилетело и опубликовало эту надпись здесь
Факт.
Унификация.

А себе я взял BMW 535d GT, которая на самом деле — 7-ка фактически (и даже больше места сзади для пассажиров) и по начинке идентична 7-ке — вот только BMW специально поставила ее классом ниже дабы не перебивать продажи 7-ки (и убрали «сверхважную» опцию — массаж на задних сидениях, при том что спереди массаж оставили — тобишь те кто ездят сзади реально все же пойдут и купят 7-ку ;)) )

Короче — «дурят» везде и разводят на деньги за шильдик. Но пока что те кто реально думают и изучают (при этом не испытывают необходимости в показухе) — могут потратить сильно меньше денег но получить то-же самое (а то и больше).
Кстати — не очень корректное сравнение ;)

Бентли — это фольксваген фаэтон. Только за шильдик и другую «внешность» прибавка к цене в два раза.

Фольсксваген и ауди (и порш) очень много платформ — идентичны.

Как пример — фольксваген туарег, audi Q7 и порш кайен — это одно и то же практически, только опять же по цене отличается ;)

Засим — верить в то что бентли лучше ауди — это чаще всего самовнушение на уровне «я ж такие бабки заплатил!»

Под понятие художественного приема попадает не только легкий отход от прямого перевода, но также локализация, подгон под реалии времени унд прочие вещи. Чем руководствовались в данном случае авторы перевода, лично я НЕ знаю — спросите у них. Но вполне возможно, что это было оправдано.

Вы — потребитель, вам элементарно неизвестны и не понятны мотивы людей, занимающихся переводами профессионально. Ну а раз так, то потребляйте молча, без публичной демонстрации дилетантства и нелепых примеров, природа которых вам не ясна.
Кешировани смарти, к сожалению, весьма глючная штука, приводящая, иногда, к непредвиденным результатам. Ждем финала Смарти3, хотя более подходящее решение уже найдено:
В нашем частном случае, мы статику кешируем через memcache и nginx отдает ее оттуда напрямую. Если не попал в кеш — проваливаемся в бекенд, который генерирует контент и сохраняет его в memcache
При этом имеем:
— возможность отдавать всю «статику» практически моментально
— при потере кеша он быстро восстанавливается
— динамические блоки собираются nginx через SSI (с предварительной проверкой на такую же закешированность в мемкеше). при этом собираются они параллельно и в случае отсутствия закешированного значения запросы «проваливаются» на разные бекенды одновременно (снижение нагрузки на каждый отдельно-взятый бекенд)
С осликом другая ситуация. Если вы опытный технолог, то проблем с осликом мало (все явные баги ослика давно изучены и описаны + есть куча вариантов их профиксить (conditional comments, expressions, behavior, filters, hasLayout, хаки наконец).

С Оперой совсем другая песня. Когда встречаешь какой-нибудь баг в Опере то практически всегда, во-первых, не понимаешь из-за чего так, во-вторых, сложно найти триггер бага, в-третьих, тупо не знаешь как фиксить да и вариантов особых нет, хаков для Оперы рабочих практически не существует. В JS еще можно сделать что-то типа if (window.opera)… а в CSS остается только переверстывать. А если еще учесть, что опера довольно часто обновляется, и что с каждой новой версией багов, как правило, становится больше, то это просто кошмар.

Плюс, у меня сложилось стойкое ощущение, что у них регрессивные и старые баги (типа глюков display:inline-block у элементов с position отличным от static, не всегда происходящим repaint/reflow, глюков с регулярными выражениями, глюков с overflow:hidden) имеют низший приоритет. Я точно знаю, что баги эти все по 10 раз зарепортены. Невозможно так долго на это забивать.
Можно даже лучше — я заворачиваю Chromium.app во «враппер» с нужными ключами:

#!/bin/bash
# Patches the Chromium application installation with command line arguments to enable extensions.
set -o errexit
app=${1:-/Applications/Chromium.app}
cat >$app/Contents/MacOS/Chromium.wrapper <<EOF
#!/bin/sh
exec $app/Contents/MacOS/Chromium --enable-extensions --enable-sync --enable-sync-extensions --enable-user-scripts "\$@"
EOF
chmod 755 $app/Contents/MacOS/Chromium.wrapper
defaults write $app/Contents/Info CFBundleExecutable Chromium.wrapper


НЛО прилетело и опубликовало эту надпись здесь
Вспомнилось с ffffound.com
Бюрократия есть. А знаете, кто ее развел? Именно такой планктон, который не желает шевелиться и делает все, что бы было меньше работы и меньше нагрузок.
НЛО прилетело и опубликовало эту надпись здесь
а так будет звучать habrahabr :)

Столько всего распиали, а статью никто не плюсует! обидна однако!
Нужно выбрать:

Инструменты » Настройки » Содержимое
затем во Шрифты и цвета выбрать размер больше чем стандартные 16

Информация

В рейтинге
Не участвует
Откуда
Москва, Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность