Страницы

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

четверг, 7 марта 2019 г.

Временные файлы при клонировании git репозитория

При клонировании большого git репозитория на диске начинает кончаться место. Это логично. При этом папка где должен лежать репозиторий в размерах не меняется. Из этого я делаю вывод что git где-то хранит временные файлы при закачке репозитория. Проблема в том, что если возникает ошибка (которая собсвенно и возникла), то эти файлы висят мертвым грузом где-то на диске. Как их найти?
Я проверял размер именно папки .git. При процессе клонирования репозитория она в размерах не меняется. Если отменить клонирование, то через некоторое время она приобретает такой размер, какой и должен быть. По логике ведь если все сохраняется туда то и размер с течением времени должен меняться? А так получается словно файлы из временной папки которые успели склонироваться перемещаются после отмены процедуры в git папку. Как это объяснить еще?
ОС — Windows 7.


Ответ

Все внутренние файлы git хранит в папке .git. Она скрытая и лежит в той папке, куда происходит клонирование. Если произошла ошибка и вы хотите клонировать заново — просто найдите и удалите эту папку.
Как правильно удалить Git tracking (контроль версий)?
При процессе клонирования репозитория она в размерах не меняется. Если отменить клонирование, то через некоторое время она приобретает такой размер, какой и должен быть.
Если в папку пишутся достаточно большие блобы (Binary Large OBject), то её размер на диске будет меняться ступенчато, хотя запись происходит непрерывно. То есть файл какое-то время открыт на запись и пишется, но его размер не пересчитывается. Потом запись прерывается (либо от ошибки, либо потому что файл завершен) и регистрируется новый размер файла
Кстати, файлы — не временные. Это постоянное внутреннее хранилище гита. Иного хранилища для временных или постоянных файлов нет. Git же работает на разных ОС и на одном диске могут быть сотни и тысячи репозиториев. Представьте, что придумано какое-то единое место для временных файлов. Это C:\TEMP\GIT\ или /tmp/git? Как не путать между собой временные файлы от разных репозиториев? Можно ведь и клонировать много сразу. Всё это внесло бы ненужную сложность

Многопоточный парсинг страниц

Для онлайн-игры пишу прогу, которая позволит получать полезные данные. Есть два метода, которые возвращают стоимость конкретного оружия на рынке для одной страны и для всех стран (74) вместе.
public void getCheapestWeapon(Weapon weapon) { //long result = 0; Map countryAndId = allCountries.getCountryAndId(); for (Map.Entry item : countryAndId.entrySet()) { //long start = System.currentTimeMillis(); getCheapestWeapon(item.getKey(), weapon); //long finish = System.currentTimeMillis(); //System.out.println(finish - start); //result += finish - start; } //System.out.println(result); }
public void getCheapestWeapon(String country, Weapon weapon) { long start = System.currentTimeMillis(); String link = MARKET_LINK + allCountries.getCountryId(country) + "/" + weapon.getPlaceOnMarket() + "/" + weapon.getQuality() + "/" + ADDITIONAL_LINK; try { Document page = Jsoup.connect(link) .userAgent("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36") .cookies(cookies) .timeout(1000) .get(); Elements table = page.getElementsByClass("price_sorted"); Element row = table.select("tr").first(); Elements columns = row.getElementsByTag("td"); Element priceCell = columns.get(3); String priceStr = priceCell.text(); double price = Double.parseDouble(priceStr.substring(0, priceStr.length() - 4)); System.out.println(country + " - " + price); } catch (IOException e) { e.printStackTrace(); } //long finish = System.currentTimeMillis(); //System.out.println(finish - start); }
Проблема в том, что при получении данных для всех стран, время на парсинг составляет в среднем 16-18 секунд что, согласитесь, очень много. Пробовал в первом методе засунуть getCheapestWeapon(item.getKey(), weapon) в отдельный поток. Ничего хорошего это не дало. Как можно реализовать одновременный парсинг всех 74-х страниц?


Ответ

В текущем виде (результаты работы getCheapestWeapon просто выводятся на консоль) проще всего использовать стандартный ExecutorService
public void getCheapestWeapon(Weapon weapon) { final int THREADS = 4; ExecutorService pool = Executors.newFixedThreadPool( THREADS );
Map countryAndId = allCountries.getCountryAndId(); for (Map.Entry item : countryAndId.entrySet()) { pool.execute( () -> getCheapestWeapon( item.getKey(), weapon ) ); }
pool.shutdown(); }
Если операция не разовая, то нужно вынести создание и остановку сервиса из метода. Т.к. основная задержка, скорее всего из-за сети (74 запроса, даже если пакет идет от клиента до сервера 50мс, съедят 7 секунд), число процессов в сервисе может превышать количество ядер (подберите экспериментально).
В качестве альтернативы, попробуйте получать у сервера больше данных меньшим количеством запросов, например убрав фильтр по странам, если вам нужна самая низкая цена.

Как вызвать статический метод класса возврающающий экземляр для использования Unity?

Есть базовый интерфейсIViewModel для всех моих ViewModel. Все ViewModel используют DevExpress POCO механизм:
public static EfCaseCollectionViewModel Create(IUnitOfWorkFactory unitOfWorkFactory = null) { return ViewModelSource.Create(() => new EfCaseCollectionViewModel(unitOfWorkFactory)); } protected EfCaseCollectionViewModel(IUnitOfWorkFactory unitOfWorkFactory = null) : base(x => x.Cases, unitOfWorkFactory ?? UnitOfWorkSource.GetUnitOfWorkFactory(),projection:t=>t.Where(x=>x.Removed==false)) { }
Во ViewModel не используется без параметрический конструктор.
Unity контейнер я создаю при старте в статическом классе:
UnityContainer unityContainer = new UnityContainer(); unityContainer.RegisterType("CaseCollection");
Во View
public EfCaseCollectionView(IUnityContainer container) { this.DataContext = GetViewModel(container); InitializeComponent(); }
private IViewModel GetViewModel(IUnityContainer container) { if (container.IsRegistered("CaseCollection")) { return container.Resolve("CaseCollection"); } return container.Resolve(); }
Но без конструктора без параметров это не работает. (MissingMethodException:'System.MissingMethodException: No parameterless constructor defined for this object.). Как правильно использовать Unity в этой ситуации?


Ответ

Спасибо за ссылку, помогла как пища для размышлений.
Честно, часть вопроса связанная с Exception не связана с основной частью тем что я просто не уследил что в CodeBehind'е View UserControl нету конструктора без параметров.
По поводу основной части. Сделал так:
public static readonly UnityContainer UnityContainer = new UnityContainer();
public static void Resolve() { UnityContainer.RegisterType("CaseCollection", new InjectionFactory(c => EfCaseCollectionViewModel.Create())); }
Этот метод вызывается в App.xaml.cs
А в View Так:
public EfCaseCollectionView() { InitializeComponent(); this.DataContext = GetViewModel(Bootstrapper.UnityContainer); }
private IViewModel GetViewModel(IUnityContainer container) { if (container.IsRegistered("CaseCollection")) { return container.Resolve("CaseCollection"); } //if not found, get default factory return container.Resolve(); }
Я не уверен что решение правильное, но мою текущую задачу оно выполнило.

В WPF приложении в Windows 7 шрифт Palatino Linotype не отобажает верхний индекс

Проблема с OpenType шрифтом Palatino Linotype в WPF приложении. На windows 8 приложение работает нормально, а вот в windows 7 верхний индекс отображается обычно. Я заметил, что проблема касается только цифр - буквы нормально отображаются в верхнем индексе. Я пробовал внедрить шрифт в приложение - ничего не меняется.

Дополнение.
С таким кодом:
145k
получается правильно:

А вот с таким (разница в содержимом индекса)
145
неправильно:


Ответ

Прошло не мало времени с момента публикации вопроса. Проблема с верхним индексом была давно была решена мной. Возможно кому-нибудь будет полезно решение. Вместо Run.Typography.Variants="Superscript", следовало использовать Run.BaselineAlignment = BaselineAlignment.Superscript. В этом случае глюк пропадает. Следует помнить, что Run.BaselineAlignment = BaselineAlignment.Superscript не меняет размер шрифта, а как известно размер шрифта верхнего индекса должен быть меньше основного шрифта. Меняйте сами размер для верхнего индекса, иначе получится неразбериха.

datatables search configure

У меня есть столбик с номерами телефонов, где они отображаются в отформатированном виде, как: +7 499 879-94-24. Поиск DataTables ищет по значению, то-есть с пробелами надо вводить номер.
Как мне сделать, чтобы при вводе в поиск без пробелов, находило номер, например: (+7499..)?


Ответ

Установите плагин для фильтрации. Этот плагид при поиске удаляет лишные значения
jQuery.fn.DataTable.ext.type.search.phoneNumber = function ( data ) { return ! data ? '' : typeof data === 'string' ? data + data.replace(/[ \-]/g, '') : data; };
пример таблицы
$(document).ready(function() { $('#example').dataTable( { columnDefs: [ { type: 'phoneNumber', target: 4 } ] } ); } );
JS в CDN: //cdn.datatables.net/plug-ins/1.10.10/filtering/type-based/phoneNumber.js
источник

Android. immortal Thread

Как известно, система может убить сервис (Service), если ей будет не хватать памяти. Но в наших силах сделать так, чтобы наш сервис ожил, когда проблема с памятью будет устранена. Делается это в методе onStartCommand возвращением соответствующей константы.
В своем приложении, к сожалению, я НЕ могу использовать сервис. Я использую обычный поток.
@Override public void run() { Looper.prepare(); // code Looper.loop(); }
Он так же как сервис работает в фоновом режиме и выполняет соответствующие команды, но так же и падает при нехватке памяти.
Ну так вот, знает кто, есть ли возможность этого избежать? Или каким-нибудь образом реализовывать логику немедленного восстановления убитого потока? Пробовал повышать приоритет у потока, так же прописывал в манифесте
android:largeHeap="true"
Не помогает.
Другой сервис использовать для поддержания потока так же нельзя =) Все что приходит на ум - использовать какой-нибудь системный receiver, который можно прописать в манифесте. При этом он должен принимать команды постоянно, хотя бы раз в минуту.


Ответ

Скорее всего вам может помочь только рассылка собственных Intent через AlarmManager. Эти интенты принимайте в собственном ресивере и запускайте сервис.
Вариант с системным интентом, рассылаемым каждую минуту, не подойдёт, т.к. его нельзя ловить в ресивере, определённом в манифесте. Только через Context.registerReceiver(). А, значит, нужен кто-то работающий, чтоб среагировать на интент.

Запуск консольной команды и получение её ответа с помощью Python 3 [дубликат]

На данный вопрос уже ответили: Python 3 и командная строка 1 ответ Как можно написать программу на Python 3 для линукса, чтобы она вбивала в терминал команду и считывала ответ?


Ответ

Для этого можно использовать функцию check_output из модуля subprocess
subprocess.check_output('ls file; exit 0', shell=True)
Здесь shell=True нужно использовать, если вся команда идёт в виде одной строки, а ; exit 0 добавлено для того, чтобы не бросалось исключение в случае, если команда вернёт не нулевой код.
Можно контролировать код возврата, используя блок try-except, отлавливая ошибки запущенных команд:
try: subprocess.check_output('ls file', shell=True) except subprocess.CalledProcessError as e: print('Команда
> {}
завершилась с кодом {}'.format(e.cmd, e.returncode))
Если нужно учитывать и поток stderr, то документацией предлается следующий способ:
subprocess.check_output("ls file; exit 0", stderr=subprocess.STDOUT, shell=True)
Здесь мы явно получаем нулевой код возврата, подавляя поднятие исключения, а также перенаправляем поток stderr на stdout