• На что обратить внимание когда создаешь файлообменник?

    EndUser
    @EndUser
    На отказ от ответственности при размещении прона и вареза.
    Ответ написан
    Комментировать
  • На что обратить внимание когда создаешь файлообменник?

    xmoonlight
    @xmoonlight
    https://sitecoder.blogspot.com
    1. Проверка ожидаемого/разрешенного "тела" закачиваемого файла
    2. Запрет на запуск из директорий хранилища для всех
    3. Шейпинг для разделения полосы пропускания
    4. ACL по доступам, общему кол-ву файлов, списку расширений, макс. объемам на папку и на файл.
    5. Распределенная система организации файловой структуры на несколько СХД
    Ответ написан
    Комментировать
  • Должен ли заказчик платить за купленные в ходе разработки библиотеки кода?

    POS_troi
    @POS_troi
    СадоМазо Админ, флудер, троль.
    Да вот какраз тут условия договора.
    Чисто по человечески библиотечку стоит отдать ибо это часть ПО за разработку которого клиент уплатил.
    Ну а то что за неё пришлось заплатить то это необходимо было обсудить с клиентом до покупки и включить доп. расходы в смету.
    Ответ написан
    Комментировать
  • Php как вывести нули после точки?

    number_format($number, 2, '.',' ');
    Ответ написан
    Комментировать
  • Как убедиться, что все дочерние процессы завершили работу?

    Удобнее всего писать в еще одном процессе. Его задачей было бы ожидать данные из очереди по get() и писать все полученное в файл. Очевидно, тут есть проблема, что процесс никогда не завершится, но она легко решается: в главном процессе вы ждете завершения всех процессов-воркеров по join(), после чего посылаете в очередь какое-нибудь "интересное" значение (я бы послал None), после чего ждете завершения процесса-писателя опять же по join(). При виде "интересного" значения пишущий процесс завершается. Ну и главный процесс тоже завершается, соответственно. Как будто бы выглядит не очень красиво, НО это нормально: нужен какой-то механизм, который бы сказал, что "в очередь больше не придут", что мы и делаем в главном процессе. Можно расширить очередь, кидать исключения, но, думаю, None вполне достаточно. Кстати, для этого можно использовать Pipe() в случае с процессами, но я бы точно не стал так делать, потому что зачем? :)

    Меня, кстати, недавно что-то подобное тревожило, искал инфу и понял, что эта задача очень похожа на шаблон producer-consumer, только у нас производящий процесс еще и обрабатывает данные, а получающий процесс только пишет. В C#, кстати, есть специальная коллекция, которая может "закрыться". А вот что пишет по этому поводу Java:

    A BlockingQueue does not intrinsically support any kind of "close" or "shutdown" operation to indicate that no more items will be added. The needs and usage of such features tend to be implementation-dependent. For example, a common tactic is for producers to insert special end-of-stream or poison objects, that are interpreted accordingly when taken by consumers.

    Special end-of-stream or poison objects, КАРЛ! Это я как бы оправдываюсь, что нормальное решение предлагаю. :)))

    Писать в главном процессе неудобно. В таком случае мы не можем вызвать join() у воркеров, поэтому нужен иной способ убедиться, что задачи закончены. Кажется, что для этого можно использовать методы task_done() и join() у очереди. Можно было бы затолкать адреса серверов в очередь (пусть будет q_in), в воркере делать q_in.get(), обрабатывать данные и класть в другую очередь (назовем ее q_out), после чего вызывать q_in.task_done(). НО у нас снова блокирующий метод q_in.join(), который ждет завершения всех задач. Т.е. такая возможность тут не катит. Да даже если бы он не блокировал, то все равно пришлось бы делать sleep() в цикле, что совсем некрасиво. Тут правильно вызывать блокирующий get() в пишущем процессе и завершаться по получению какого-то сигнала. Этим сигналом будет либо отправка "интересного" значения (и в случае записи в главном процессе это сделать некому, х̶о̶т̶я̶ ̶м̶о̶ж̶н̶о̶ ̶с̶д̶е̶л̶а̶т̶ь̶ ̶о̶т̶д̶е̶л̶ь̶н̶ы̶й̶ ̶п̶р̶о̶ц̶е̶с̶с̶ ̶д̶л̶я̶ ̶э̶т̶о̶г̶о̶,̶ ̶г̶о̶в̶о̶р̶и̶т̶ ̶и̶з̶в̶р̶а̶щ̶е̶н̶е̶ц̶), как я уже сказал выше, либо же можно ввести еще одну сущность, назовем ее "глобальный счетчик". Т.е. он должен уменьшаться после того, как в очередь складывается результат. А главный процесс может проверять, не равен ли этот счетчик нулю после того, как сработал get() на очереди. И если равен, то выйти из бесконечного цикла, заджойниться к воркеркам, и завершиться. Но ведь это менее красиво, чем отдельный пишущий процесс: придется создать глобальную переменную и если с тредами можно было бы обойтись простым локом, то в случае с процессами там какой-то геморрой 100%, я никогда так не делал, ведь глобальные переменные - зло. В общем, с какой стороны не подойти, нужно писать в отдельном процессе, иначе можно изобрести что-нибудь.

    Хочу еще пару вещей тут заметить.

    Вам точно нужно писать по мере поступления данных? Быть может, это не нужно. Ведь там постоянные открытия/закрытия файла будут, это тоже некий оверхед, нужно ли это по-настоящему? Кроме того, нужны ли именно процессы? Там сложная обработка данных, сколько она времени занимает относительно ввода/вывода? Если некритично мало, то лучше использовать треды, в таком случае с ними все может оказаться быстрее. Кроме того, с тредами появляется возможность использовать глобальные объекты, которые я все-таки использую, хотя они и зло. Можно, например, вместо Queue использовать list/set/dict. В cpython они является threadsafe, но лучше на всякий случай использовать локи в таком случае, они вносят совсем небольшой оверхед, но при этом 100% защитят от интересных проблем (я бы сделал класс LockedIterator в таком случае, чтобы было универсально для всего). Главный плюс в том, что они значительно быстрее, чем Queue, даже с локами (по моим тестам, хотя, думаю, можно это и нагуглить). А ведь вам, по сути, прелести Queue и не нужны, если юзать треды. То есть вы уверены, что процессы + плавно писать в файл - это быстрее/удобнее/лучше, чем просто сделать треды без Queue, дождаться завершения, все записать в файл? Хотя тут тоже могут быть сложности с оперативой, если очень много писать нужно.

    Кроме того, а почему не, например, ansible? Он умеет опрашивать хосты и принимать в себя плагины на питоне. Кроме того, там есть асинхронные задачи, я их не использовал, но, по-моему, они справятся.
    Ответ написан
    3 комментария
  • Разница между облаком и VPS?

    saboteur_kiev
    @saboteur_kiev Куратор тега Системное администрирование
    software engineer
    VPS это VPS, конкретная виртуальная машина. Она избавляет вас от необходимости покупать конкретное железо и настраивать драйвера, так как может быть поднята в виде виртуальной запущенной машине как на старом железе, так и на новом, без переустановки драйверов и прочего хлама.

    Облако это облако. Под облаком обычно подразумевается кластеризация машин таким образом, что ресурсы распределяются между ними и легко мигрируют с конкретной машины на другую машины прозрачно для пользователя. Избавляет от необходимости перемещать виртуальные машины на другой сервер вручную, упрощает расширение и добавление ресурсов, которые в кластере машин грубо говоря бесконечны, ибо добавляться могут на лету, без перезапуска "хоста" - "хостом" в облаке является кластер из машин, а не один конкретный хост-сервер.

    SaaS это SaaS. Когда виртуализируется не ОС, а конкретный сервер, конкретное приложение. Избавляет вас от необходимости задумываться об операционной системе.

    То есть каждая из вышеупомянутых технологий, может существовать как отдельно друг от друга, так и представлять собой более высокий уровень абстрации, избавляя от рутины.
    Ответ написан
    Комментировать
  • Из чего собрать домашний сервер?

    MaxDukov
    @MaxDukov
    впишусь в проект как SRE/DevOps.
    купите старенький нетбук на атоме.
    Ответ написан
    Комментировать
  • Putty. При закрытии останавливается процесс?

    saboteur_kiev
    @saboteur_kiev Куратор тега Linux
    software engineer
    1. Если разрывается связь, процессу отправляется сигнал SIGHUP, что означает "трубка повешена, связь с терминалом оборвана, пора завершаться".
    Чтобы предотвратить, пользуются командой nohup, которая блокирует этот сигнал, и при разрыве связи продолжает эмулировать терминал, сохраняя весь вывод на "экран" в файл nohup.out

    2. использовать экранные менеджеры screen или tmux, которые изначально сохранают сессию, даже если разорвать связь, и можно переподключившись, восстановить сессию.
    Ответ написан
    Комментировать
  • Питон для инженера?

    @throughtheether
    human after all
    Какие инженерные задачи вы решали с помощью питона?
    Генерация файлов конфигурации для коммутаторов на jinja. Простые веб-интерфейсы (flask, bottle). Парсинг логов и экспортированных данных (lxml). Учет ресурсов (база на sqlite + веб-интерфейс + выгрузка отчетов).
    UPD: Забыл упомянуть, генерация трафика при помощи scapy в целях отлова бага.

    Почему не баш/пауэршелл?
    Проще было написать один раз на python и запускать где необходимо.
    Ответ написан
    1 комментарий
  • Питон для инженера?

    xSkyFoXx
    @xSkyFoXx
    1) Какие инженерные задачи вы решали с помощью питона? Почему не баш/пауэршелл?

    Как и любой другой язык общего назначения, практически любую задачу автоматизации можно реализовать на python. Просто наблюдайте за собой и смотрите, что бы вам хотелось автоматизировать в работе или бытовой жизни. Я, например, парсю серверные логи, вычленяю из них ошибки и визуализирую себе это поверх http.

    2) Есть ли какие-то ресурсы, где можно посмотреть на реализацию питоновских скриптов в администрировании? гитхаб?

    Собственно, Ansible. К тому же он сам написан на python, по этому любые новые плагины или какие-то продвинутые автоматизации вы должны будете писать на python.
    Ответ написан
    5 комментариев
  • Не переходит в цикл, хотя условия выполнены. Где ошибка?

    @idap
    интересуюсь python, latex, linux, ML, AI
    Приоритет операций нужно учитывать, видимо:
    1 in (1, 2, 3) == True
    даст False, поскольку сначала выполнится (1, 2, 3) == True, что вернёт False, и затем получится проверка 1 in False, что есть False.
    А вот так правильно:
    (1 in (1, 2, 3)) == True
    даст True.
    А вот так ещё правильнее:
    if 1 in (1, 2, 3):
        pass
    Ответ написан
    Комментировать
  • Нормально ли процессы от имени рута на веб сервере?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Since mpm-itk has to be able to setuid(), it runs as root (although restricted with POSIX capabilities and seccomp v2 where possible) until the request is parsed and the vhost determined. This means that any code execution hole before the request is parsed will be a potential root security hole. (The most likely place is probably in mod_ssl.) This is not likely to change in the near future, as socket passing, the most likely alternative solution, is very hard to get to work properly in a number of common use cases (e.g. SSL).


    mpm-itk.sesse.net
    Ответ написан
    Комментировать
  • Порекомендуйте ресурсы по изучению настройки веб-сервера под Django?

    @deliro
    SSH - та же консоль, только удалённая. Знать там нужно только основные команды nano cat ls ln rm cp mv mkdir и т.п.
    Обязательно прочитай мануал к virtualenv. Можно и без него, если джанго-приложение на сервере одно, но лучше с ним. Удобнее.
    С nginx'ом особо колдовать не нужно, вот тут написано, как его настроить.
    HTTP-серверов для джанго основных два: Gunicorn и uWSGI.

    На дев-сервере вообще ничего не нужно. В джанго уже есть сервер (runserver) и база SQLite, которую устанавливать тоже не нужно.

    Никаких книг тут не нужно, достаточно почитать пару Getting Started к используемым технологиям.
    Ответ написан
    5 комментариев
  • Как настроить импорт прайсов из excel в БД?

    grigruss
    @grigruss
    Пока не задал ни одного вопроса... только отвечаю.
    Отталкиваться от закономерностей в полях прайсов. Допустим поле цены обычно содерит только цифры, а поле с наименованием либо в первом, либо во втором столбце (первый часто делают для нумерации позиций). Бывает столбец с типом валюты. Бывает скидочный столбец... И учитывая определенные особенности можно задавать условия для загрузки в БД. Например, если первый столбец имеет числовое значение -> идём ко второму столбцу -> если здесь текст: определяем как имя товара -> следующий столбец: если имеется "%" значит скидка -> следующий: если "руб" или "usd" значит тип валюты -> следующий: если число значит цена.
    P.S.: а можно вообще сделать подгрузку правил из внешнего файла, к примеру в формате INI или XML. А в нём указывать, какое по счёту поле в куда загружать. И в обычном блокноте за пару минут создавать правила для прайса нового контрагента.
    Ответ написан
    6 комментариев
  • Возможно ли SSH подключение к устройству не с белым IP?

    mobilesfinks
    @mobilesfinks
    сисадмин *nix
    Если заказать у МТС белый адрес - да (если есть такая возможность).
    А так - нет.
    Ответ написан
    Комментировать
  • Что это за CMS?

    @maxyc_webber
    Web-программист
    какой ответ вы хотите услышать? вы часто принимаете решение портировать рабочее ПО на что-то непонятное? Да будет много подводных камней, которые придется решать вам самим, ибо информации о такой cms нет в яндексе. в гугле не смотрел
    Ответ написан
    3 комментария
  • Возможно ли SSH подключение к устройству не с белым IP?

    @Amigo83
    IT-шник
    Только если на шлюзе сделать проброс портов.
    Ответ написан
    2 комментария
  • Как правильно переопределить конструктор класса?

    @adv-tsk
    Full Stack Web Developer
    Это происходит потому, что конструктор класса date принимает всего три аргумента: year, month, day, а Вы пытаетесь передать ему дополнительные аргументы. Вот как Вы должны были поступить в Вашем случае:

    class MyClass(date):
    
        __slots__ = '_expiry',
    
        def __new__(cls, m_year, m_month, m_day, expiry=None, *args, **kwargs):
            return super(MyClass, cls).__new__(cls, m_year, m_month, m_day)
    
        def __init__(self, m_year, m_month, m_day, expiry=None, *args, **kwargs):
            if expiry:
                self._expiry = expiry
            else:
                self._expiry = date(m_year, m_month, m_day)
    
        @property
        def expiry(self):
            return {'year': self._expiry.year,
                    'month': self._expiry.month,
                    'day': self._expiry.day}
    
    >>> q = MyClass(2015, 5, 5, expiry=date(2015, 5, 1))
    >>> print(q.expiry)
    >>> {'year': 2015, 'day': 1, 'month': 5}

    UPD: То что Вы называете конструктором класса, является инициализатором класса, т.е. тот самый метод __init__(). Конструктором класса является метод __new__().
    Ответ написан
    3 комментария