Страницы

Поиск по вопросам

четверг, 30 мая 2019 г.

Получить список пакетов, установленных пользователем

apt-get иногда выдаёт сообщение, что некоторые пакеты были установлены автоматически и их можно удалить командой apt-get autoremove. Значит, где-то хранится признак, по какой причине был установлен тот или иной пакет.
Как получить список пакетов, установленных по запросу пользователя, без автоматически добавленных по зависимостям, и, если возможно, с датой установки?


Ответ

с помощью «тёплого лампового» aptitude
$ aptitude search -F '%p' '!~M ~i' с помощью apt-mark
$ apt-mark showmanual

дату/время запуска (а также параметры и ещё много другой информции) программы apt-get можно найти в файлах /var/log/apt/*, программы aptitude — в файлах /var/log/aptitude*, программы dpkg (её ведь можно запустить и вручную для установки пакета из скачанного «вручную» файла) — в файлах /var/log/dpkg.log*. что плохо — все эти файлы ротируются и (насколько помню, но стоит это уточнить в настройках logrotate) со временем удаляются.

доп. информация:
поисковые шаблоны aptitude настройка того, как отображаются пакеты в aptitude

дополнение по поводу даты установки. вообще-то она не фиксируется в «базе данных» dpkg, но более или менее релевантный результат можно получить, например, по дате последней модификации файлов /var/lib/dpkg/info/имя-пакета* (например, имя-пакета[:архитектура].list, содержащий список файлов пакета).
при распаковке архивов, содержащихся в файле с пакетом, программа dpkg указанные файлы (как минимум) перезаписывает (более точный алгоритм можно узнать в документации dpkg, или непосредственно в её исходных кодах).
как-нибудь так:
#!/bin/bash
export arch=$(dpkg --print-architecture)
dostat() { stat --printf="$1\t%y
" $2 }
apt-mark showmanual | while read p; do if [ -f /var/lib/dpkg/info/$p.list ]; then dostat $p /var/lib/dpkg/info/$p.list elif [ -f /var/lib/dpkg/info/$p:$arch.list ]; then dostat $p /var/lib/dpkg/info/$p:$arch.list else echo $p fi done
пример вывода:
2vcard 2010-03-25 11:56:42.000000000 +0300 abcde 2013-07-20 20:50:31.000000000 +0400 abiword 2013-07-20 22:48:50.000000000 +0400 abook 2013-07-20 22:48:51.000000000 +0400 acl 2013-07-20 22:46:20.000000000 +0400 acpi 2013-07-20 20:50:34.000000000 +0400 acpid 2013-07-20 20:50:34.000000000 +0400 adduser 2013-07-20 20:48:04.000000000 +0400 alien 2013-07-20 20:50:38.000000000 +0400 alsa-base 2013-07-20 22:45:48.000000000 +0400

rails puma постоянный рост используемой памяти

Имеется небольшое приложение на rails(4.2.6), в качестве веб-сервера используется nginx+puma(3.4.0). Сервер Debian 8.1 64bit. Заметил одну странную вещь, с каждым запросом, используемое процессами puma количество памяти растет, и никогда не снижается(во время отсутствия каких либо запросов). Это приводит к тому, что ОЗУ на сервере (512 мб) заканчивается, и останавливается служба postgres(9.4). Пробовал разное количество воркеров, нитей, работа в кластерном режиме и в обычном - результат всегда один и тот же. После нескольких тяжелых запросов ОЗУ заканчивается. Неужели так и должно быть? Какие есть пути устранения такой проблемы? По информации, которую я нашел, Puma - это один из лучших выборов для избежания проблемы медленных клиентов и долгих запросов. Текущий конфиг такой:
#!/usr/bin/env puma
...
threads 2,4
... workers 1
preload_app!
on_restart do puts 'Refreshing Gemfile' ENV["BUNDLE_GEMFILE"] = "/home/.../current/Gemfile" end
on_worker_boot do ActiveSupport.on_load(:active_record) do ActiveRecord::Base.establish_connection end end


Ответ

Описанное в ответе реально не совсем правда
GC может освобождать память, но темпы освобождения могут быть меньше темпов роста. Вне синтетических тестов обычно так и есть.
Ответ подлежит переработке с учётом этого факта.

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

Беда с большими объектами в том, что они требуют большие последовательные области памяти. И если такой блок в пуле не находится, то... пул ещё увеличивается на такую величину, чтобы большой объект влез!
Эту проблему можно было б частично победить, используя сборщик мусора с "уплотнением" (compaction), когда GC в процессе работы "перекладывает" мелкие объекты поближе друг к другу, тем самым образуя более крупные последовательные области свободной памяти. Это же могло бы позволить отдавать крупные "хвосты" незанятой памяти обратно в ОС. Но это здорово усложняет работу С-шных расширений, которые запоминают, где был объект, непосредственно по адресу в памяти. Нельзя просто сказать им "я вон тот объект подвинул, имей в виду".

Сделать можно много чего.
Пол-гигабайта на целое рельсовое приложение и хранилища данных это... крайне немного. Есть смысл добавить, если не физической ОЗУ, то хотя бы подкачки. Подкрутить garbage collector на более осторожное расширение пула и частые срабатывания. Это вряд ли поможет, но может немножко отсрочить неизбежное. Это довольно обширная и опасная тема, требующая тщательного стресс-тестирования на каждое изменение. (Самый богатый на приключения) Реально снизить пиковое потребление памяти, отдавая большие ответы по кусочкам, чтобы GC успевал подчищать то, что уже отослано клиенту. Есть ActionController::Live, с помощью которого можно писать ответ в поток по кусочкам, не загружая все исходные данные для него в память.

Как для обычной задачи задать параметр TaskCreationOptions.LongRunning?

Пример от andreycha паттерна throttling
public async Task CheckServers() { var servers = new List(10000) { ... };
const int ConcurrencyLevel = 100;
// запускаем первые 100 запросов var tasks = servers.Take(ConcurrencyLevel).Select(GetVersion).ToList(); int nextIndex = ConcurrencyLevel;
while (tasks.Count > 0) { // дожидаемся завершения любого запроса var completedTask = await Task.WhenAny(tasks);
// удаляем его из списка tasks.Remove(completedTask);
// добавляем новый запрос, если таковые остались if (nextIndex < servers.Count) { tasks.Add(GetVersion(servers[nextIndex++])); }
string rfbVersion = await completedTask; // работаем с версией } }
Как в подобной реализации красиво задать параметр TaskCreationOptions.LongRunning задачам? Это вообще возможно без использования Task.Factory.StartNew?


Ответ

Смотрите. Давайте разделим Task'и и другие асинхронные функции на те, которые ограничены процессором (то есть, занимают фиксированный поток длительное время), и остальные.
Для первых функций TaskCreationOptions.LongRunning имеет смысл, т. к. мы не хотим надолго блокировать поток из пула потоков. Но такие функции обычно предоставляются в виде синхронных функций, которые мы запускаем через Task.Run. Так что можно, при желании, запустить и через Task.Factory.StartNew
Для остальных асинхронных функций нету понятия «поток, в котором функция бежит», и большую часть времени Task не бежит нигде, просто ожидая окончания await. Для таких функций TaskCreationOptions.LongRunning лишено смысла, и задать его сложно (если и можно вообще). Но в этом случае эта опция и не нужна.

Как в javascript “закрывать” div при клике вне этого дива? (без jquery)

Добрый день.
Как в javascript "закрывать" div при клике вне этого дива?
Тот же вопрос, только надо написать без jQuery


Ответ

Это делается, например, так:
document.onclick = function() { document.getElementById("block").style.display = "none"; } function onDivClick(e) { e = e || window.event; e.stopPropagation(); } #block { background-color: #ddf; border: 2px solid #ffd; width: 100px; height: 100px; }


Логический оператор с бесконечным количеством итераций

Скажите пожалуйста, есть ли такой оператор, который будет выполнять какую либо итерацию, до того момента, пока логическое условие не будет выполнено? Это не for ведь в нем надо указывать кол-во итераций, а мне нужно немного другое то, что я описывал выше. Спасибо.


Ответ

Начать исполнять и продолжать пока условие верно:
boolean someBoolean = true; while(someBoolean) { //тут можно присвоить false для someBoolean для завершения бесконечного цикла }

Либо можно и через цикл for вот так
boolean someBoolean = true; //в цикле for сперва идёт инициализация переменной-чсётчика, в конце действие с ней (инкрементация, например), //а по середине - условие - пока оно верно, цикл будет продолжаться for (;someBoolean;) { //тут можно присвоить false для someBoolean для завершения бесконечного цикла }

Если же хотя б одну итерацию надо сделать вне зависимости от начального значения someBoolean, то можно написать так:
boolean someBoolean = false; do { //хотя бы раз, но выполнится } while(someBoolean);

Библиотека под unix для работы с изображениями

Подскажите пожалуйста либу под unix, которая позволит выполнять все функции с изображениям: обрезать, склеивать, переворачивать, и т.д.
Желательно уже скомпилированную и с описанным API.


Ответ

вопрос не по стандартам, но
http://www.boost.org/doc/libs/1_61_0/libs/gil/doc/index.html http://www.imagemagick.org/Magick++/Image++.html - с чем в этом примере вы не смогли разобраться? еще более высокоуровневая либа http://cimg.eu/ что значит "уже скомпилированную"? если у вас проблемы со сборкой библиотеки с нуля - для убунты есть готовый пакет libmagick++-dev

проблема при десериализации пустого элемента xml

есть простой хмл

проблема в том что Dprtm_code может быть как заполнен 234234234 так и нет . создал схему :
//... //...
создал класс и в нем описал эти поля:
//... private long? dprtm_codeField; private string dprtm_nameField;
[XmlElementAttribute(IsNullable=true)] public long? Dprtm_code { get { return this.dprtm_codeField; } set { this.dprtm_codeField = value; } } public string Dprtm_name { get { return this.dprtm_nameField; } set { this.dprtm_nameField = value; } } //...
но при десериализации хмл с пустым кодом падает ошибка приведения типов. собственно вопрос: как правильно объявить елементы которые могут быть пустыми в xml?


Ответ

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

То есть, обязательно должен быть атрибут nil из указанного пространства имён. Его корректно обрабатывает XmlSerializer (полагаю, что используется именно он).
При сериализации атрибут xsi:nil будет добавляться автоматически при необходимости.
Без этого атрибута валидация по схеме тоже не проходит.