2017-01-14 8 views
13

Начиная с сегодняшнего дня я получаю много"ПРЕДУПРЕЖДЕНИЕ conda.gateways.disk: exp_backoff_fn (47): Uncaught с потерей мощности Errno 41" во время "Конда установки"

ПРЕДУПРЕЖДЕНИЕ conda.gateways.disk: exp_backoff_fn (47): Uncaught с потерей мощности Errno 41

предупреждения при попытке обновить или установить пакеты с помощью conda install или conda update. Например:

(...) C:\Users\...> conda install numba 
Fetching package metadata ........... 
Solving package specifications: . 

Package plan for installation in environment C:\...: 

The following packages will be DOWNGRADED due to dependency conflicts: 

    numba: 0.30.0-np111py35_0 --> 0.30.1-np111py35_0 

Proceed ([y]/n)? y 

numba-0.30.0-np111p35_0 100% |###############################| Time: 0:00:00 2.50 MB/s 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 
WARNING conda.gateways.disk:exp_backoff_fn(47): Uncaught backoff with errno 41 

Пакеты установлены после этого, но все эти предупреждения, похоже, указывают на то, что что-то не работает должным образом.

OS: Windows 10 64 bit 
conda: 4.3.4 

Не могли бы вы сказать, что мне нужно сделать, чтобы исправить эти предупреждения? Или я могу игнорировать их?

ответ

13

Эти предупреждения, которые вы видите, являются «нормальными» в соответствии с текущим деревом источника conda. Чтобы понять происхождение вышеупомянутых предупреждений, давайте посмотрим на исходный код в вопросах и недавнюю фиксацию в репозитории conda (https://github.com/conda/conda). Соответствующий исходный код, который печатает предупреждения вы видите следующее:

https://github.com/conda/conda/blob/4.3.4/conda/gateways/disk/init.py

# -*- coding: utf-8 -*- 
from __future__ import absolute_import, division, print_function, unicode_literals 

import sys 
from errno import EACCES, ENOENT, EPERM, EPROTOTYPE 
from logging import getLogger 
from os.path import basename 
from time import sleep 

from ...common.compat import on_win 

log = getLogger(__name__) 

MAX_TRIES = 7 


def exp_backoff_fn(fn, *args, **kwargs): 
    """Mostly for retrying file operations that fail on Windows due to virus scanners""" 
    max_tries = kwargs.pop('max_tries', MAX_TRIES) 
    if not on_win: 
     return fn(*args, **kwargs) 

    import random 
    # with max_tries = 6, max total time ~= 3.2 sec 
    # with max_tries = 7, max total time ~= 6.5 sec 
    for n in range(max_tries): 
     try: 
      result = fn(*args, **kwargs) 
     except (OSError, IOError) as e: 
      log.trace(repr(e)) 
      if e.errno in (EPERM, EACCES): 
       if n == max_tries-1: 
        raise 
       sleep_time = ((2 ** n) + random.random()) * 0.1 
       caller_frame = sys._getframe(1) 
       log.trace("retrying %s/%s %s() in %g sec", 
          basename(caller_frame.f_code.co_filename), 
          caller_frame.f_lineno, 
          fn.__name__, 
          sleep_time) 
       sleep(sleep_time) 
      elif e.errno in (ENOENT, EPROTOTYPE): 
       # errno.ENOENT File not found error/No such file or directory 
       # errno.EPROTOTYPE OSError(41, 'The directory is not empty') 
       raise 
      else: 
       log.warn("Uncaught backoff with errno %d", e.errno) 
       raise 
     else: 
      return result 

Из выше исходного кода, что, как представляется, будет предупреждение выброшены на Windows, которые могут появляться, когда

Повторная попытка файловых операций, которые не выполняются в Windows из-за вирусных сканеров

Отправляясь в специфику, используя https://msdn.microsoft.com/en-us/library/t3ayayh1.aspx, оказывается, что ERRNO 41 соответствует

ENOTEMPTY: каталог не пустой

, который сигнализирует о том, что указанная директория не пуста. Это неперехваченная ошибка, потому что они не имеют ветви, которая имеет дело с таким родом ошибки (ENOTEMPTY), в то время как, например, у них есть в случае, если это еще одна ошибка, как EPERM или EACCES.
В совершить https://github.com/conda/conda/commit/fb2a783d9b9371559b5ea82aaf8ae631c2ce0450#diff-3757ed9862260ae3b54768b3e482e3fe
они явно удалить отчет EPROTOTYPE как OSError(41, 'The directory is not empty'), так что теперь вы видите, что количество ошибок сообщается как предупреждение в

log.warn("Uncaught backoff with errno %d", e.errno) 

Другая часть модифицируют находится в https://github.com/conda/conda/blob/fb2a783d9b9371559b5ea82aaf8ae631c2ce0450/conda/gateways/disk/delete.py, в функции delete_trash(), так теперь, если вы включите информационный журнал, скорее всего, вы увидите строку, такую ​​как

«Невозможно полностью очистить каталог мусора% s \ nВыберите% d оставшихся файлов."

включается

log.info("Unable to fully clean trash directory %s\nThere are %d remaining file(s).", 
       trash_dir, len(files_remaining)) 

Теперь, delete_trash() вызывается как ваши команды, которые вы цитируете (установка, обновление):
https://github.com/conda/conda/blob/f4b386476307e3979679957292d4f6e4c581df03/conda/cli/main_install.py
https://github.com/conda/conda/blob/a26b1eff17dcaf12f03aea5bbe8dee1e01308de7/conda/cli/main_update.py

Как можно видеть, delete_trash() запускается соответственно в файлах 'install' и 'update', которые ранее упоминались соответственно следующими фрагментами кода:

from ..gateways.disk.delete import delete_trash 

# some other code ... 

def execute(args, parser): 
    install(args, parser, 'install') 
    delete_trash() 

и

from ..gateways.disk.delete import delete_trash 

# some other code ... 

def execute(args, parser): 
    install(args, parser, 'update') 
    delete_trash() 

delete_trash() будет инициировать этот путь кода через backoff_rmdir() или backoff_unlink(), что в конечном счете приведет к предупреждению вы видите из exp_backoff_fn(), как показано ранее.
Таким образом, чтобы подвести итог, основная цепь вызовов будет

update or install --> delete_trash() --> backoff_rmdir() or backoff_unlink() --> exp_backoff_fn() --> your warning message 

В соответствии с изменениями исходного кода, сделанных в хранилище, разработчики считают, чем они предупреждают, что вы можете спокойно игнорировать, потому что эти предупреждения случаются на этапе «очистки» команд обновления или установки, то есть после того, как операция обновления или установки была успешно выполнена.
Я не мог сказать, что на 100% вы можете спокойно игнорировать эти предупреждения. Если после нескольких попыток команда удалять каталог мусора завершается успешно, тогда нет никаких проблем. Но если это не удастся, вы столкнетесь с проблемой, что этот каталог будет становиться все больше и больше в результате не удалять его. Было несколько выпусков, открытых в репо для этого, и я не знаю, покрывают ли исправления код, который вы нажмете. Мое впечатление, что это не так. Чтобы получить дополнительную информацию, вы можете активировать уровень информационного журнала.


UPDATE: Этот вопрос https://github.com/conda/conda/issues/4164 точно упомянуть предупреждения, которые сообщили, что люди получали долго и установить обновление времени из всех попыток. Поскольку я упоминал, что после всех попыток (экспоненциальных отступлений) операция удаления может быть успешной или неудачной, этот человек также упоминает этот аспект в своем отчете.
Как вы можете видеть здесь
https://github.com/conda/conda/issues/3664
есть несколько хаков, что люди используют, чтобы решить проблему длительного времени ожидания из-за повторные попытки и будут также сделать следующий запуск вашей команды conda install X или conda update X без предупреждения. Эти предложения являются:

  1. (ускорив время для повторных попыток/удалить) установить MAX_TRIES = 1 в вашей копии conda/gateways/disk/init.py
  2. удалить .trash каталог перед запуском следующего conda install X или conda update X. См. https://github.com/conda/conda/issues/3664 для обходного пути, используемого некоторыми людьми для автоматизации удаления этого каталога с использованием простых скриптов. Это должно быть безопасно для этого.

Так что ответы на вопросы будут:
1) Вы можете использовать обходной путь, упомянутый в https://github.com/conda/conda/issues/3664, который использует следующий Powershell скрипт (и другой сценарий):

$cir = conda info --root 
$trash_dir = "$($cir)\pkgs\.trash" 
if (Test-Path $trash_dir){ 
    Remove-Item -Recurse -Force $trash_dir 
} 
conda --debug update --all --yes --quiet 

в основном очистить каталог .trash;

2) Вы можете спокойно игнорировать предупреждения в том смысле, что они не влияют на функциональность; проблема в том, что чем больше .trash будет заселено, тем больше времени и повторов будет продолжаться, чтобы удалить элементы, чтобы вы столкнулись с проблемами производительности; как вы упомянули, это своего рода «утечка», но это не влияет на функциональность. Этот каталог должен быть опустошен и удален, так как он содержит мусор, который больше не нужен. Система попытается удалить его, но, возможно, не сможет этого сделать. Поэтому используйте 1).


UPDATE 2: Как уже упоминалось в одном из моих комментариев, один из ключевых изменений в файле conda/gateways/disk/__init__.py, который был «FIX» (https://github.com/conda/conda/commit/6cb3be39aec1c738678ae27b3a264941d08c859a), который сделал его 4.3.6 версии Конда (conda 4.3.6 release info), который разрешает данное предупреждение.
Ключевым моментом, чтобы не видеть, что предупреждение, имея ветвь, которая явно ловит и сделок с видом ошибки объяснена прежде. Теперь, когда произойдет ошибка типа ENOTEMPTY (которая является ошибкой, вызвавшей печать предупреждения в этом случае), это будет поймано и не пойдет в ветку, которая печатает предупреждение, изученное вопросом. Чтобы понять основные различия, в версии 4.3.4 это

elif e.errno in (ENOENT, EPROTOTYPE):     
    raise 
else: 
    log.warn("Uncaught backoff with errno %d", e.errno) 
    raise 

в то время как в версии 4.3.6 стал:

elif e.errno in (ENOENT, ENOTEMPTY):  
    raise 
else: 
    log.warn("Uncaught backoff with errno %s %d", errorcode[e.errno], e.errno) 
    raise 

и вы ясно видите, что теперь за эту ошибку не войдет в ветвь else, поэтому вы не увидите это сообщение в этом случае.

+0

Не могли бы вы пояснить, почему вы говорите «вы можете безопасно игнорировать предупреждение», если он не в состоянии укомплектовать очистки (удалить неиспользуемые и ненужные папки) после установки? Это больше похоже на «утечку памяти», но с данными на жестком диске вместо RAM. (Я не знаю, что это слово в этом случае.) – MSeifert

+0

я сказал, потому что я не могу гарантировать 100%, если вы можете активировать «инфо» уровень журнала мы могли видеть кастрированный баран мы видим строку «Не удается полностью очистить каталог мусора% s \ n Распечатывается% d оставшихся файлов (ов). Я согласен, что это проблема. Не могли бы вы активировать информационный журнал? Помните, хотя эти попытки были неудачными, не означает, что все попытки, которые он попытается, не сработают ... – fedepad

+0

Если я очищу корзину, предупреждения все равно появятся.Однако мусор в основном пуст, поэтому я думаю, что он просто терпит неудачу несколько раз и, в конце концов, его убирает. Однако если я вручную изменю «MAX_TRIES», мусор не будет очищен. Поэтому у меня есть предупреждения и полный мусор. Любая другая идея, кроме как удалить предупреждающее сообщение, которое могло бы помочь? – MSeifert

1

Эти предупреждения присутствовали на моем компьютере с Конда версии 4.3.4 и 4.3.5, но не в версии 4.2.x, а не в последней версии (4.3.6) больше.

Я думаю, что лучший способ «исправить» проблема будет обновлять Конда:

$ conda update conda 

или понизить до 4,2:

$ conda install conda=4.2 

С обеих версий предупреждения исчезают.